gpxpy-1.3.5/ 0000755 0000765 0000024 00000000000 13436454537 012630 5 ustar tkr staff 0000000 0000000 gpxpy-1.3.5/PKG-INFO 0000644 0000765 0000024 00000015137 13436454537 013734 0 ustar tkr staff 0000000 0000000 Metadata-Version: 1.1
Name: gpxpy
Version: 1.3.5
Summary: GPX file parser and GPS track manipulation library
Home-page: http://www.trackprofiler.com/gpxpy/index.html
Author: Tomo Krajina
Author-email: tkrajina@gmail.com
License: Apache License, Version 2.0
Description: [](https://travis-ci.org/tkrajina/gpxpy)
[](https://coveralls.io/github/tkrajina/gpxpy?branch=master)
# gpxpy -- GPX file parser
This is a simple Python library for parsing and manipulating GPX files. GPX is an XML based format for GPS tracks.
You can see it in action on [my online GPS track editor and organizer](http://www.trackprofiler.com).
There is also a Golang port of gpxpy: [gpxgo](http://github.com/tkrajina/gpxgo).
See also [srtm.py](https://github.com/tkrajina/srtm.py) if your track lacks elevation data.
## Usage
```python
import gpxpy
import gpxpy.gpx
# Parsing an existing file:
# -------------------------
gpx_file = open('test_files/cerknicko-jezero.gpx', 'r')
gpx = gpxpy.parse(gpx_file)
for track in gpx.tracks:
for segment in track.segments:
for point in segment.points:
print('Point at ({0},{1}) -> {2}'.format(point.latitude, point.longitude, point.elevation))
for waypoint in gpx.waypoints:
print('waypoint {0} -> ({1},{2})'.format(waypoint.name, waypoint.latitude, waypoint.longitude))
for route in gpx.routes:
print('Route:')
for point in route.points:
print('Point at ({0},{1}) -> {2}'.format(point.latitude, point.longitude, point.elevation))
# There are many more utility methods and functions:
# You can manipulate/add/remove tracks, segments, points, waypoints and routes and
# get the GPX XML file from the resulting object:
print('GPX:', gpx.to_xml())
# Creating a new file:
# --------------------
gpx = gpxpy.gpx.GPX()
# Create first track in our GPX:
gpx_track = gpxpy.gpx.GPXTrack()
gpx.tracks.append(gpx_track)
# Create first segment in our GPX track:
gpx_segment = gpxpy.gpx.GPXTrackSegment()
gpx_track.segments.append(gpx_segment)
# Create points:
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(2.1234, 5.1234, elevation=1234))
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(2.1235, 5.1235, elevation=1235))
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(2.1236, 5.1236, elevation=1236))
# You can add routes and waypoints, too...
print('Created GPX:', gpx.to_xml())
```
## GPX Version:
gpx.py can parse and generate GPX 1.0 and 1.1 files. Note that the generated file will always be a valid XML document, but it may not be (strictly speaking) a valid GPX document. For example, if you set gpx.email to "my.email AT mail.com" the generated GPX tag won't confirm to the regex pattern. And the file won't be valid. Most applications will ignore such errors, but... Be aware of this!
Be aware that the gpxpy object model *is not 100% equivalent* with the underlying GPX XML file schema. That's because the library object model works with both GPX 1.0 and 1.1.
For example, GPX 1.0 specified a `speed` attribute for every track point, but that was removed in GPX 1.1. If you parse GPX 1.0 and serialize back with `gpx.to_xml()` everything will work fine. But if you have a GPX 1.1 object, changes in the `speed` attribute will be lost after `gpx.to_xml()`. If you want to force using 1.0, you can `gpx.to_xml(version="1.0")`. Another possibility is to use `extensions` to save the speed in GPX 1.1.
## GPX extensions
gpx.py preserves GPX extensions. They are stored as [ElementTree](https://docs.python.org/2/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) DOM objects. Extensions are part of GPX 1.1, and will be ignored when serializing a GPX object in a GPX 1.0 file.
## XML parsing
If lxml is available, then it will be used for XML parsing.
Otherwise minidom is used.
Note that lxml is 2-3 times faster so, if you can choose -- use it :)
The GPX version is automatically determined when parsing by reading the version attribute in the gpx node. If this attribute is not present then the version is assumed to be 1.0. A specific version can be forced by setting the `version` parameter in the parse function. Possible values for the 'version' parameter are `1.0`, `1.1` and `None`.
## Pull requests
OK, so you found a bug and fixed it. Before sending a pull request -- check that all tests are OK with Python 2.7 and Python 3.4+.
Run all tests with:
$ python -m unittest test
$ python3 -m unittest test
Run a single test with:
$ python -m unittest test.GPXTests.test_haversine_and_nonhaversine
$ python3 -m unittest test.GPXTests.test_haversine_and_nonhaversine
## GPXInfo
The repository contains a little command line utility to extract basic statistics from a file.
Example usage:
$ gpxinfo voznjica.gpx
File: voznjica.gpx
Length 2D: 63.6441229018
Length 3D: 63.8391428454
Moving time: 02:56:03
Stopped time: 00:21:38
Max speed: 14.187909492m/s = 51.0764741713km/h
Total uphill: 1103.1626183m
Total downhill: 1087.7812703m
Started: 2013-06-01 06:46:53
Ended: 2013-06-01 10:23:45
## License
GPX.py is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
Platform: UNKNOWN
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
gpxpy-1.3.5/gpxinfo 0000755 0000765 0000024 00000011503 13347377211 014222 0 ustar tkr staff 0000000 0000000 #!/usr/bin/env python
"""
Command line utility to extract basic statistics from gpx file(s)
"""
import pdb
import sys as mod_sys
import logging as mod_logging
import math as mod_math
import argparse as mod_argparse
import gpxpy as mod_gpxpy
KM_TO_MILES = 0.621371
M_TO_FEET = 3.28084
def format_time(time_s):
if not time_s:
return 'n/a'
elif args.seconds:
return str(int(time_s))
else:
minutes = mod_math.floor(time_s / 60.)
hours = mod_math.floor(minutes / 60.)
return '%s:%s:%s' % (str(int(hours)).zfill(2), str(int(minutes % 60)).zfill(2), str(int(time_s % 60)).zfill(2))
def format_long_length(length):
if args.miles:
return '{:.3f}miles'.format(length / 1000. * KM_TO_MILES)
else:
return '{:.3f}km'.format(length / 1000.)
def format_short_length(length):
if args.miles:
return '{:.2f}ft'.format(length * M_TO_FEET)
else:
return '{:.2f}m'.format(length)
def format_speed(speed):
if not speed:
speed = 0
if args.miles:
return '{:.2f}mph'.format(speed * KM_TO_MILES * 3600. / 1000.)
else:
return '{:.2f}m/s = {:.2f}km/h'.format(speed, speed * 3600. / 1000.)
def print_gpx_part_info(gpx_part, indentation=' '):
"""
gpx_part may be a track or segment.
"""
length_2d = gpx_part.length_2d()
length_3d = gpx_part.length_3d()
print('%sLength 2D: %s' % (indentation, format_long_length(length_2d)))
print('%sLength 3D: %s' % (indentation, format_long_length(length_3d)))
moving_time, stopped_time, moving_distance, stopped_distance, max_speed = gpx_part.get_moving_data()
print('%sMoving time: %s' % (indentation, format_time(moving_time)))
print('%sStopped time: %s' % (indentation, format_time(stopped_time)))
#print('%sStopped distance: %s' % (indentation, format_short_length(stopped_distance)))
print('%sMax speed: %s' % (indentation, format_speed(max_speed)))
print('%sAvg speed: %s' % (indentation, format_speed(moving_distance / moving_time) if moving_time > 0 else "?"))
uphill, downhill = gpx_part.get_uphill_downhill()
print('%sTotal uphill: %s' % (indentation, format_short_length(uphill)))
print('%sTotal downhill: %s' % (indentation, format_short_length(downhill)))
start_time, end_time = gpx_part.get_time_bounds()
print('%sStarted: %s' % (indentation, start_time))
print('%sEnded: %s' % (indentation, end_time))
points_no = len(list(gpx_part.walk(only_points=True)))
print('%sPoints: %s' % (indentation, points_no))
if points_no > 0:
distances = []
previous_point = None
for point in gpx_part.walk(only_points=True):
if previous_point:
distance = point.distance_2d(previous_point)
distances.append(distance)
previous_point = point
print('%sAvg distance between points: %s' % (indentation, format_short_length(sum(distances) / len(list(gpx_part.walk())))))
print('')
def print_gpx_info(gpx, gpx_file):
print('File: %s' % gpx_file)
if gpx.name:
print(' GPX name: %s' % gpx.name)
if gpx.description:
print(' GPX description: %s' % gpx.description)
if gpx.author_name:
print(' Author: %s' % gpx.author_name)
if gpx.author_email:
print(' Email: %s' % gpx.author_email)
print_gpx_part_info(gpx)
for track_no, track in enumerate(gpx.tracks):
for segment_no, segment in enumerate(track.segments):
print(' Track #%s, Segment #%s' % (track_no, segment_no))
print_gpx_part_info(segment, indentation=' ')
def run(gpx_files):
if not gpx_files:
print('No GPX files given')
mod_sys.exit(1)
for gpx_file in gpx_files:
try:
gpx = mod_gpxpy.parse(open(gpx_file))
print_gpx_info(gpx, gpx_file)
except Exception as e:
mod_logging.exception(e)
print('Error processing %s' % gpx_file)
mod_sys.exit(1)
def make_parser():
parser = mod_argparse.ArgumentParser(usage='%(prog)s [-s] [-m] [-d] [file ...]',
description='Command line utility to extract basic statistics from gpx file(s)')
parser.add_argument('-s', '--seconds', action='store_true',
help='print times as N seconds, rather than HH:MM:SS')
parser.add_argument('-m', '--miles', action='store_true',
help='print distances and speeds using miles and feet')
parser.add_argument('-d', '--debug', action='store_true',
help='show detailed logging')
return parser
if __name__ == '__main__':
args, gpx_files = make_parser().parse_known_args()
if args.debug:
mod_logging.basicConfig(level=mod_logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
run(gpx_files)
gpxpy-1.3.5/gpxpy.egg-info/ 0000755 0000765 0000024 00000000000 13436454537 015471 5 ustar tkr staff 0000000 0000000 gpxpy-1.3.5/gpxpy.egg-info/PKG-INFO 0000644 0000765 0000024 00000015137 13436454537 016575 0 ustar tkr staff 0000000 0000000 Metadata-Version: 1.1
Name: gpxpy
Version: 1.3.5
Summary: GPX file parser and GPS track manipulation library
Home-page: http://www.trackprofiler.com/gpxpy/index.html
Author: Tomo Krajina
Author-email: tkrajina@gmail.com
License: Apache License, Version 2.0
Description: [](https://travis-ci.org/tkrajina/gpxpy)
[](https://coveralls.io/github/tkrajina/gpxpy?branch=master)
# gpxpy -- GPX file parser
This is a simple Python library for parsing and manipulating GPX files. GPX is an XML based format for GPS tracks.
You can see it in action on [my online GPS track editor and organizer](http://www.trackprofiler.com).
There is also a Golang port of gpxpy: [gpxgo](http://github.com/tkrajina/gpxgo).
See also [srtm.py](https://github.com/tkrajina/srtm.py) if your track lacks elevation data.
## Usage
```python
import gpxpy
import gpxpy.gpx
# Parsing an existing file:
# -------------------------
gpx_file = open('test_files/cerknicko-jezero.gpx', 'r')
gpx = gpxpy.parse(gpx_file)
for track in gpx.tracks:
for segment in track.segments:
for point in segment.points:
print('Point at ({0},{1}) -> {2}'.format(point.latitude, point.longitude, point.elevation))
for waypoint in gpx.waypoints:
print('waypoint {0} -> ({1},{2})'.format(waypoint.name, waypoint.latitude, waypoint.longitude))
for route in gpx.routes:
print('Route:')
for point in route.points:
print('Point at ({0},{1}) -> {2}'.format(point.latitude, point.longitude, point.elevation))
# There are many more utility methods and functions:
# You can manipulate/add/remove tracks, segments, points, waypoints and routes and
# get the GPX XML file from the resulting object:
print('GPX:', gpx.to_xml())
# Creating a new file:
# --------------------
gpx = gpxpy.gpx.GPX()
# Create first track in our GPX:
gpx_track = gpxpy.gpx.GPXTrack()
gpx.tracks.append(gpx_track)
# Create first segment in our GPX track:
gpx_segment = gpxpy.gpx.GPXTrackSegment()
gpx_track.segments.append(gpx_segment)
# Create points:
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(2.1234, 5.1234, elevation=1234))
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(2.1235, 5.1235, elevation=1235))
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(2.1236, 5.1236, elevation=1236))
# You can add routes and waypoints, too...
print('Created GPX:', gpx.to_xml())
```
## GPX Version:
gpx.py can parse and generate GPX 1.0 and 1.1 files. Note that the generated file will always be a valid XML document, but it may not be (strictly speaking) a valid GPX document. For example, if you set gpx.email to "my.email AT mail.com" the generated GPX tag won't confirm to the regex pattern. And the file won't be valid. Most applications will ignore such errors, but... Be aware of this!
Be aware that the gpxpy object model *is not 100% equivalent* with the underlying GPX XML file schema. That's because the library object model works with both GPX 1.0 and 1.1.
For example, GPX 1.0 specified a `speed` attribute for every track point, but that was removed in GPX 1.1. If you parse GPX 1.0 and serialize back with `gpx.to_xml()` everything will work fine. But if you have a GPX 1.1 object, changes in the `speed` attribute will be lost after `gpx.to_xml()`. If you want to force using 1.0, you can `gpx.to_xml(version="1.0")`. Another possibility is to use `extensions` to save the speed in GPX 1.1.
## GPX extensions
gpx.py preserves GPX extensions. They are stored as [ElementTree](https://docs.python.org/2/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) DOM objects. Extensions are part of GPX 1.1, and will be ignored when serializing a GPX object in a GPX 1.0 file.
## XML parsing
If lxml is available, then it will be used for XML parsing.
Otherwise minidom is used.
Note that lxml is 2-3 times faster so, if you can choose -- use it :)
The GPX version is automatically determined when parsing by reading the version attribute in the gpx node. If this attribute is not present then the version is assumed to be 1.0. A specific version can be forced by setting the `version` parameter in the parse function. Possible values for the 'version' parameter are `1.0`, `1.1` and `None`.
## Pull requests
OK, so you found a bug and fixed it. Before sending a pull request -- check that all tests are OK with Python 2.7 and Python 3.4+.
Run all tests with:
$ python -m unittest test
$ python3 -m unittest test
Run a single test with:
$ python -m unittest test.GPXTests.test_haversine_and_nonhaversine
$ python3 -m unittest test.GPXTests.test_haversine_and_nonhaversine
## GPXInfo
The repository contains a little command line utility to extract basic statistics from a file.
Example usage:
$ gpxinfo voznjica.gpx
File: voznjica.gpx
Length 2D: 63.6441229018
Length 3D: 63.8391428454
Moving time: 02:56:03
Stopped time: 00:21:38
Max speed: 14.187909492m/s = 51.0764741713km/h
Total uphill: 1103.1626183m
Total downhill: 1087.7812703m
Started: 2013-06-01 06:46:53
Ended: 2013-06-01 10:23:45
## License
GPX.py is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
Platform: UNKNOWN
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
gpxpy-1.3.5/gpxpy.egg-info/SOURCES.txt 0000644 0000765 0000024 00000002421 13436454537 017354 0 ustar tkr staff 0000000 0000000 LICENSE.txt
MANIFEST.in
NOTICE.txt
README.md
gpxinfo
setup.py
test.py
gpxpy/__init__.py
gpxpy/geo.py
gpxpy/gpx.py
gpxpy/gpxfield.py
gpxpy/gpxxml.py
gpxpy/parser.py
gpxpy/utils.py
gpxpy.egg-info/PKG-INFO
gpxpy.egg-info/SOURCES.txt
gpxpy.egg-info/dependency_links.txt
gpxpy.egg-info/top_level.txt
test_files/Mojstrovka.gpx
test_files/cerknicko-jezero-no-creator.gpx
test_files/cerknicko-jezero-with-elevations-zero.gpx
test_files/cerknicko-jezero-without-elevations.gpx
test_files/cerknicko-jezero.gpx
test_files/cerknicko-without-times.gpx
test_files/custom_schema_locations.gpx
test_files/default_schema_locations.gpx
test_files/first_and_last_elevation.gpx
test_files/gpx-with-node-with-comments.gpx
test_files/gpx1.0_with_all_fields.gpx
test_files/gpx1.1_with_all_fields.gpx
test_files/gpx1.1_with_extensions.gpx
test_files/gpx1.1_with_extensions_without_namespaces.gpx
test_files/korita-zbevnica.gpx
test_files/route.gpx
test_files/track-with-empty-segment.gpx
test_files/track-with-extremes.gpx
test_files/track-with-small-floats.gpx
test_files/track_with_dilution_errors.gpx
test_files/track_with_speed.gpx
test_files/unicode.gpx
test_files/unicode2.gpx
test_files/unicode_with_bom.gpx
test_files/unicode_with_bom_noencoding.gpx
test_files/validation_gpx10.gpx
test_files/validation_gpx11.gpx gpxpy-1.3.5/gpxpy.egg-info/top_level.txt 0000644 0000765 0000024 00000000006 13436454537 020217 0 ustar tkr staff 0000000 0000000 gpxpy
gpxpy-1.3.5/gpxpy.egg-info/dependency_links.txt 0000644 0000765 0000024 00000000001 13436454537 021537 0 ustar tkr staff 0000000 0000000
gpxpy-1.3.5/MANIFEST.in 0000644 0000765 0000024 00000000134 13347375562 014365 0 ustar tkr staff 0000000 0000000 include README.md LICENSE.txt NOTICE.txt
include test.py
recursive-include test_files *.gpx
gpxpy-1.3.5/test.py 0000644 0000765 0000024 00000453101 13436453437 014163 0 ustar tkr staff 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright 2011 Tomo Krajina
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Run all tests with:
$ python -m unittest test
Run lxml parser test with:
$ python -m unittest test.LxmlTest
Run single test with:
$ python -m unittest test.GPXTests.test_method
"""
from __future__ import print_function
import logging as mod_logging
import os as mod_os
import time as mod_time
import codecs as mod_codecs
import copy as mod_copy
import datetime as mod_datetime
import random as mod_random
import math as mod_math
import sys as mod_sys
import unittest as mod_unittest
import xml.dom.minidom as mod_minidom
try:
import lxml.etree as mod_etree # Load LXML or fallback to cET or ET
except:
try:
import xml.etree.cElementTree as mod_etree
except:
import xml.etree.ElementTree as mod_etree
import gpxpy as mod_gpxpy
import gpxpy.gpx as mod_gpx
import gpxpy.gpxfield as mod_gpxfield
import gpxpy.parser as mod_parser
import gpxpy.geo as mod_geo
from gpxpy.utils import make_str
from gpxpy.utils import total_seconds
PYTHON_VERSION = mod_sys.version.split(' ')[0]
mod_logging.basicConfig(level=mod_logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
def equals(object1, object2, ignore=None):
""" Testing purposes only """
if not object1 and not object2:
return True
if not object1 or not object2:
print('Not obj2')
return False
if not object1.__class__ == object2.__class__:
print('Not obj1')
return False
attributes = []
for attr in dir(object1):
if not ignore or not attr in ignore:
if not hasattr(object1, '__call__') and not attr.startswith('_'):
if not attr in attributes:
attributes.append(attr)
for attr in attributes:
attr1 = getattr(object1, attr)
attr2 = getattr(object2, attr)
if attr1 == attr2:
return True
if not attr1 and not attr2:
return True
if not attr1 or not attr2:
print('Object differs in attribute %s (%s - %s)' % (attr, attr1, attr2))
return False
if not equals(attr1, attr2):
print('Object differs in attribute %s (%s - %s)' % (attr, attr1, attr2))
return None
return True
def custom_open(filename, encoding=None):
if PYTHON_VERSION[0] == '3':
return open(filename, encoding=encoding)
elif encoding == 'utf-8':
mod_codecs.open(filename, encoding='utf-8')
return open(filename)
def cca(number1, number2):
return 1 - number1 / number2 < 0.999
def get_dom_node(dom, path):
path_parts = path.split('/')
result = dom
for path_part in path_parts:
if '[' in path_part:
tag_name = path_part.split('[')[0]
n = int(path_part.split('[')[1].replace(']', ''))
else:
tag_name = path_part
n = 0
candidates = []
for child in result.childNodes:
if child.nodeName == tag_name:
candidates.append(child)
try:
result = candidates[n]
except Exception:
raise Exception('Can\'t fint %sth child of %s' % (n, path_part))
return result
##def pretty_print_xml(xml):
## dom = mod_minidom.parseString(xml)
## print(dom.toprettyxml())
## input()
def node_strip(text):
if text is None:
return ''
return text.strip()
def elements_equal(e1, e2):
if node_strip(e1.tag) != node_strip(e2.tag): return False
if node_strip(e1.text) != node_strip(e2.text): return False
if node_strip(e1.tail) != node_strip(e2.tail): return False
if e1.attrib != e2.attrib: return False
if len(e1) != len(e2): return False
return all(elements_equal(c1, c2) for c1, c2 in zip(e1, e2))
def print_etree(e1, indent=''):
tag = ['{0}tag: |{1}|\n'.format(indent,e1.tag)]
for att, value in e1.attrib.items():
tag.append('{0}-att: |{1}| = |{2}|\n'.format(indent, att, value))
tag.append('{0}-text: |{1}|\n'.format(indent, e1.text))
tag.append('{0}-tail: |{1}|\n'.format(indent, e1.tail))
for subelem in e1:
tag.append(print_etree(subelem, indent+'__|'))
return ''.join(tag)
class GPXTests(mod_unittest.TestCase):
"""
Add tests here.
"""
def parse(self, file, encoding=None, version=None):
f = custom_open('test_files/%s' % file, encoding=encoding)
parser = mod_parser.GPXParser(f)
gpx = parser.parse(version)
f.close()
if not gpx:
print('Parser error: %s' % parser.get_error())
return gpx
def reparse(self, gpx):
xml = gpx.to_xml()
parser = mod_parser.GPXParser(xml)
gpx = parser.parse()
if not gpx:
print('Parser error while reparsing: %s' % parser.get_error())
return gpx
def test_simple_parse_function(self):
# Must not throw any exception:
with custom_open('test_files/korita-zbevnica.gpx', encoding='utf-8') as f:
mod_gpxpy.parse(f)
def test_simple_parse_function_invalid_xml(self):
try:
mod_gpxpy.parse('\'' in str(e)))
self.assertTrue(isinstance(e, mod_gpx.GPXXMLSyntaxException))
self.assertTrue(e.__cause__)
try:
# more checks if lxml:
import lxml.etree as mod_etree
import xml.parsers.expat as mod_expat
self.assertTrue(isinstance(e.__cause__, mod_etree.XMLSyntaxError)
or isinstance(e.__cause__, mod_expat.ExpatError))
except:
pass
def test_creator_field(self):
gpx = self.parse('cerknicko-jezero.gpx')
self.assertEqual(gpx.creator, "GPSBabel - http://www.gpsbabel.org")
def test_no_creator_field(self):
gpx = self.parse('cerknicko-jezero-no-creator.gpx')
self.assertEqual(gpx.creator, None)
def test_to_xml_creator(self):
gpx = self.parse('cerknicko-jezero.gpx')
xml = gpx.to_xml()
self.assertTrue('creator="GPSBabel - http://www.gpsbabel.org"' in xml)
gpx2 = self.reparse(gpx)
self.assertEqual(gpx2.creator, "GPSBabel - http://www.gpsbabel.org")
def test_waypoints_equality_after_reparse(self):
gpx = self.parse('cerknicko-jezero.gpx')
gpx2 = self.reparse(gpx)
self.assertTrue(equals(gpx.waypoints, gpx2.waypoints))
self.assertTrue(equals(gpx.routes, gpx2.routes))
self.assertTrue(equals(gpx.tracks, gpx2.tracks))
self.assertTrue(equals(gpx, gpx2))
def test_waypoint_time(self):
gpx = self.parse('cerknicko-jezero.gpx')
self.assertTrue(gpx.waypoints[0].time)
self.assertTrue(isinstance(gpx.waypoints[0].time, mod_datetime.datetime))
def test_add_elevation(self):
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, elevation=100))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13))
gpx.add_elevation(10)
self.assertEqual(gpx.tracks[0].segments[0].points[0].elevation, 110)
self.assertEqual(gpx.tracks[0].segments[0].points[1].elevation, None)
gpx.add_elevation(-20)
self.assertEqual(gpx.tracks[0].segments[0].points[0].elevation, 90)
self.assertEqual(gpx.tracks[0].segments[0].points[1].elevation, None)
def test_get_duration(self):
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13,
time=mod_datetime.datetime(2013, 1, 1, 12, 30)))
self.assertEqual(gpx.get_duration(), 0)
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[1].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13))
self.assertEqual(gpx.get_duration(), 0)
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[2].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13,
time=mod_datetime.datetime(2013, 1, 1, 12, 30)))
gpx.tracks[0].segments[2].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13,
time=mod_datetime.datetime(2013, 1, 1, 12, 31)))
self.assertEqual(gpx.get_duration(), 60)
def test_remove_elevation(self):
gpx = self.parse('cerknicko-jezero.gpx')
for point, track_no, segment_no, point_no in gpx.walk():
self.assertTrue(point.elevation is not None)
gpx.remove_elevation(tracks=True, waypoints=True, routes=True)
for point, track_no, segment_no, point_no in gpx.walk():
self.assertTrue(point.elevation is None)
xml = gpx.to_xml()
self.assertFalse('' in xml)
def test_remove_time_tracks_only(self):
gpx = self.parse('cerknicko-jezero.gpx')
for point, track_no, segment_no, point_no in gpx.walk():
self.assertTrue(point.time is not None)
gpx.remove_time()
for point, track_no, segment_no, point_no in gpx.walk():
self.assertTrue(point.time is None)
def test_remove_time_all(self):
gpx = mod_gpx.GPX()
t0 = mod_datetime.datetime(2018, 7, 15, 12, 30, 0)
t1 = mod_datetime.datetime(2018, 7, 15, 12, 31, 0)
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
p0 = mod_gpx.GPXTrackPoint(latitude=13.0, longitude=13.0, time=t0)
p1 = mod_gpx.GPXTrackPoint(latitude=13.1, longitude=13.1, time=t1)
gpx.tracks[0].segments[0].points.append(p0)
gpx.tracks[0].segments[0].points.append(p1)
gpx.waypoints.append(mod_gpx.GPXWaypoint(latitude=13.0, longitude=13.0, time=t0))
gpx.waypoints.append(mod_gpx.GPXWaypoint(latitude=13.1, longitude=13.1, time=t1))
gpx.routes.append(mod_gpx.GPXRoute())
p0 = mod_gpx.GPXRoutePoint(latitude=13.0, longitude=13.0, time=t0)
p1 = mod_gpx.GPXRoutePoint(latitude=13.1, longitude=13.1, time=t1)
gpx.routes[0].points.append(p0)
gpx.routes[0].points.append(p1)
gpx.remove_time(all=True)
for point, track_no, segment_no, point_no in gpx.walk():
self.assertTrue(point.time is None)
for point in gpx.waypoints:
self.assertTrue(point.time is None)
for route in gpx.routes:
for point, _ in route.walk():
self.assertTrue(point.time is None)
def test_has_times_false(self):
gpx = self.parse('cerknicko-without-times.gpx')
self.assertFalse(gpx.has_times())
def test_has_times(self):
gpx = self.parse('korita-zbevnica.gpx')
self.assertTrue(len(gpx.tracks) == 4)
# Empty -- True
self.assertTrue(gpx.tracks[0].has_times())
# Not times ...
self.assertTrue(not gpx.tracks[1].has_times())
# Times OK
self.assertTrue(gpx.tracks[2].has_times())
self.assertTrue(gpx.tracks[3].has_times())
def test_unicode_name(self):
gpx = self.parse('unicode.gpx', encoding='utf-8')
name = gpx.waypoints[0].name
self.assertTrue(make_str(name) == 'šđčćž')
def test_unicode_2(self):
with custom_open('test_files/unicode2.gpx', encoding='utf-8') as f:
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
gpx.to_xml()
def test_unicode_bom(self):
# TODO: Check that this file has the BOM and is unicode before checking gpxpy handling
gpx = self.parse('unicode_with_bom.gpx', encoding='utf-8')
name = gpx.waypoints[0].name
self.assertTrue(make_str(name) == 'test')
def test_unicode_bom_noencoding(self):
gpx = self.parse('unicode_with_bom_noencoding.gpx', encoding='utf-8')
name = gpx.waypoints[0].name
self.assertTrue(make_str(name) == 'bom noencoding ő')
def test_force_version(self):
gpx = self.parse('unicode_with_bom.gpx', version = '1.1', encoding='utf-8')
# TODO: Implement new test. Current gpx is not valid (extensions using default namespace).
# I don't want to edit this file without easy verification that it has the BOM and is unicode
## security = gpx.waypoints[0].extensions['security']
##
## self.assertTrue(make_str(security) == 'Open')
def test_nearest_location_1(self):
gpx = self.parse('korita-zbevnica.gpx')
location = mod_geo.Location(45.451058791, 14.027903696)
nearest_location, track_no, track_segment_no, track_point_no = gpx.get_nearest_location(location)
point = gpx.tracks[track_no].segments[track_segment_no].points[track_point_no]
self.assertTrue(point.distance_2d(location) < 0.001)
self.assertTrue(point.distance_2d(nearest_location) < 0.001)
location = mod_geo.Location(1, 1)
nearest_location, track_no, track_segment_no, track_point_no = gpx.get_nearest_location(location)
point = gpx.tracks[track_no].segments[track_segment_no].points[track_point_no]
self.assertTrue(point.distance_2d(nearest_location) < 0.001)
location = mod_geo.Location(50, 50)
nearest_location, track_no, track_segment_no, track_point_no = gpx.get_nearest_location(location)
point = gpx.tracks[track_no].segments[track_segment_no].points[track_point_no]
self.assertTrue(point.distance_2d(nearest_location) < 0.001)
def test_long_timestamps(self):
# Check if timestamps in format: 1901-12-13T20:45:52.2073437Z work
gpx = self.parse('Mojstrovka.gpx')
# %Y-%m-%dT%H:%M:%SZ'
self.assertEqual(gpx.tracks[0].segments[0].points[0].elevation, 1614.678000)
self.assertEqual(gpx.tracks[0].segments[0].points[0].time, mod_datetime.datetime(1901, 12, 13, 20, 45, 52, 207343, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertEqual(gpx.tracks[0].segments[0].points[1].time, mod_datetime.datetime(1901, 12, 13, 20, 45, 52, 207000, tzinfo=mod_gpxfield.SimpleTZ()))
def test_reduce_gpx_file(self):
f = open('test_files/Mojstrovka.gpx')
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
f.close()
max_reduced_points_no = 50
started = mod_time.time()
points_original = gpx.get_track_points_no()
time_original = mod_time.time() - started
gpx.reduce_points(max_reduced_points_no)
points_reduced = gpx.get_track_points_no()
result = gpx.to_xml()
if mod_sys.version_info[0] != 3:
result = result.encode('utf-8')
started = mod_time.time()
parser = mod_parser.GPXParser(result)
parser.parse()
time_reduced = mod_time.time() - started
print(time_original)
print(points_original)
print(time_reduced)
print(points_reduced)
self.assertTrue(points_reduced < points_original)
self.assertTrue(points_reduced < max_reduced_points_no)
def test_smooth_without_removing_extreemes_preserves_point_count(self):
gpx = self.parse('first_and_last_elevation.gpx')
l = len(list(gpx.walk()))
gpx.smooth(vertical=True, horizontal=False)
self.assertEqual(l, len(list(gpx.walk())))
def test_smooth_without_removing_extreemes_preserves_point_count_2(self):
gpx = self.parse('first_and_last_elevation.gpx')
l = len(list(gpx.walk()))
gpx.smooth(vertical=False, horizontal=True)
self.assertEqual(l, len(list(gpx.walk())))
def test_smooth_without_removing_extreemes_preserves_point_count_3(self):
gpx = self.parse('first_and_last_elevation.gpx')
l = len(list(gpx.walk()))
gpx.smooth(vertical=True, horizontal=True)
self.assertEqual(l, len(list(gpx.walk())))
def test_clone_and_smooth(self):
f = open('test_files/cerknicko-jezero.gpx')
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
f.close()
original_2d = gpx.length_2d()
original_3d = gpx.length_3d()
cloned_gpx = gpx.clone()
cloned_gpx.reduce_points(2000, min_distance=10)
cloned_gpx.smooth(vertical=True, horizontal=True)
cloned_gpx.smooth(vertical=True, horizontal=False)
print('2d:', gpx.length_2d())
print('2d cloned and smoothed:', cloned_gpx.length_2d())
print('3d:', gpx.length_3d())
print('3d cloned and smoothed:', cloned_gpx.length_3d())
self.assertTrue(gpx.length_3d() == original_3d)
self.assertTrue(gpx.length_2d() == original_2d)
self.assertTrue(gpx.length_3d() > cloned_gpx.length_3d())
self.assertTrue(gpx.length_2d() > cloned_gpx.length_2d())
def test_reduce_by_min_distance(self):
with open('test_files/cerknicko-jezero.gpx') as f:
gpx = mod_gpxpy.parse(f)
min_distance_before_reduce = 1000000
for point, track_no, segment_no, point_no in gpx.walk():
if point_no > 0:
previous_point = gpx.tracks[track_no].segments[segment_no].points[point_no - 1]
if point.distance_3d(previous_point) < min_distance_before_reduce:
min_distance_before_reduce = point.distance_3d(previous_point)
gpx.reduce_points(min_distance=10)
min_distance_after_reduce = 1000000
for point, track_no, segment_no, point_no in gpx.walk():
if point_no > 0:
previous_point = gpx.tracks[track_no].segments[segment_no].points[point_no - 1]
if point.distance_3d(previous_point) < min_distance_after_reduce:
min_distance_after_reduce = point.distance_3d(previous_point)
self.assertTrue(min_distance_before_reduce < min_distance_after_reduce)
self.assertTrue(min_distance_before_reduce < 10)
self.assertTrue(10 < min_distance_after_reduce)
def test_moving_stopped_times(self):
f = open('test_files/cerknicko-jezero.gpx')
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
f.close()
print(gpx.get_track_points_no())
#gpx.reduce_points(1000, min_distance=5)
print(gpx.get_track_points_no())
length = gpx.length_3d()
print('Distance: %s' % length)
gpx.reduce_points(2000, min_distance=10)
gpx.smooth(vertical=True, horizontal=True)
gpx.smooth(vertical=True, horizontal=False)
moving_time, stopped_time, moving_distance, stopped_distance, max_speed = gpx.get_moving_data(stopped_speed_threshold=0.1)
print('-----')
print('Length: %s' % length)
print('Moving time: %s (%smin)' % (moving_time, moving_time / 60.))
print('Stopped time: %s (%smin)' % (stopped_time, stopped_time / 60.))
print('Moving distance: %s' % moving_distance)
print('Stopped distance: %s' % stopped_distance)
print('Max speed: %sm/s' % max_speed)
print('-----')
# TODO: More tests and checks
self.assertTrue(moving_distance < length)
print('Dakle:', moving_distance, length)
self.assertTrue(moving_distance > 0.75 * length)
self.assertTrue(stopped_distance < 0.1 * length)
def test_split_on_impossible_index(self):
f = open('test_files/cerknicko-jezero.gpx')
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
f.close()
track = gpx.tracks[0]
before = len(track.segments)
track.split(1000, 10)
after = len(track.segments)
self.assertTrue(before == after)
def test_split(self):
f = open('test_files/cerknicko-jezero.gpx')
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
f.close()
track = gpx.tracks[1]
track_points_no = track.get_points_no()
before = len(track.segments)
track.split(0, 10)
after = len(track.segments)
self.assertTrue(before + 1 == after)
print('Points in first (split) part:', len(track.segments[0].points))
# From 0 to 10th point == 11 points:
self.assertTrue(len(track.segments[0].points) == 11)
self.assertTrue(len(track.segments[0].points) + len(track.segments[1].points) == track_points_no)
# Now split the second track
track.split(1, 20)
self.assertTrue(len(track.segments[1].points) == 21)
self.assertTrue(len(track.segments[0].points) + len(track.segments[1].points) + len(track.segments[2].points) == track_points_no)
def test_split_and_join(self):
f = open('test_files/cerknicko-jezero.gpx')
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
f.close()
track = gpx.tracks[1]
original_track = track.clone()
track.split(0, 10)
track.split(1, 20)
self.assertTrue(len(track.segments) == 3)
track.join(1)
self.assertTrue(len(track.segments) == 2)
track.join(0)
self.assertTrue(len(track.segments) == 1)
# Check that this split and joined track is the same as the original one:
self.assertTrue(equals(track, original_track))
def test_remove_point_from_segment(self):
f = open('test_files/cerknicko-jezero.gpx')
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
f.close()
track = gpx.tracks[1]
segment = track.segments[0]
original_segment = segment.clone()
segment.remove_point(3)
print(segment.points[0])
print(original_segment.points[0])
self.assertTrue(equals(segment.points[0], original_segment.points[0]))
self.assertTrue(equals(segment.points[1], original_segment.points[1]))
self.assertTrue(equals(segment.points[2], original_segment.points[2]))
# ...but:
self.assertTrue(equals(segment.points[3], original_segment.points[4]))
self.assertTrue(len(segment.points) + 1 == len(original_segment.points))
def test_distance(self):
distance = mod_geo.distance(48.56806, 21.43467, None, 48.599214, 21.430878, None)
print(distance)
self.assertTrue(distance > 3450 and distance < 3500)
def test_haversine_and_nonhaversine(self):
haversine_dist = mod_geo.distance(0, 0, 0, 0.1, 0.1, 0, haversine=True)
nonhaversine_dist = mod_geo.distance(0, 0, 0, 0.1, 0.1, 0, haversine=False)
print("haversine_dist=", haversine_dist)
print("nonhaversine_dist=", nonhaversine_dist)
self.assertTrue(haversine_dist != nonhaversine_dist)
self.assertTrue(abs(haversine_dist - nonhaversine_dist) < 15)
def test_haversine_distance(self):
loc1 = mod_geo.Location(1, 2)
loc2 = mod_geo.Location(2, 3)
self.assertEqual(loc1.distance_2d(loc2),
mod_geo.distance(loc1.latitude, loc1.longitude, None, loc2.latitude, loc2.longitude, None))
loc1 = mod_geo.Location(1, 2)
loc2 = mod_geo.Location(3, 4)
self.assertEqual(loc1.distance_2d(loc2),
mod_geo.distance(loc1.latitude, loc1.longitude, None, loc2.latitude, loc2.longitude, None))
loc1 = mod_geo.Location(1, 2)
loc2 = mod_geo.Location(3.1, 4)
self.assertEqual(loc1.distance_2d(loc2),
mod_geo.haversine_distance(loc1.latitude, loc1.longitude, loc2.latitude, loc2.longitude))
loc1 = mod_geo.Location(1, 2)
loc2 = mod_geo.Location(2, 4.1)
self.assertEqual(loc1.distance_2d(loc2),
mod_geo.haversine_distance(loc1.latitude, loc1.longitude, loc2.latitude, loc2.longitude))
def test_horizontal_smooth_remove_extremes(self):
with open('test_files/track-with-extremes.gpx', 'r') as f:
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
points_before = gpx.get_track_points_no()
gpx.smooth(vertical=False, horizontal=True, remove_extremes=True)
points_after = gpx.get_track_points_no()
print(points_before)
print(points_after)
self.assertTrue(points_before - 2 == points_after)
def test_vertical_smooth_remove_extremes(self):
with open('test_files/track-with-extremes.gpx', 'r') as f:
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
points_before = gpx.get_track_points_no()
gpx.smooth(vertical=True, horizontal=False, remove_extremes=True)
points_after = gpx.get_track_points_no()
print(points_before)
print(points_after)
self.assertTrue(points_before - 1 == points_after)
def test_horizontal_and_vertical_smooth_remove_extremes(self):
with open('test_files/track-with-extremes.gpx', 'r') as f:
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
points_before = gpx.get_track_points_no()
gpx.smooth(vertical=True, horizontal=True, remove_extremes=True)
points_after = gpx.get_track_points_no()
print(points_before)
print(points_after)
self.assertTrue(points_before - 3 == points_after)
def test_positions_on_track(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
gpx.tracks.append(track)
segment = mod_gpx.GPXTrackSegment()
track.segments.append(segment)
location_to_find_on_track = None
for i in range(1000):
latitude = 45 + i * 0.001
longitude = 45 + i * 0.001
elevation = 100 + i * 2
point = mod_gpx.GPXTrackPoint(latitude=latitude, longitude=longitude, elevation=elevation)
segment.points.append(point)
if i == 500:
location_to_find_on_track = mod_gpx.GPXWaypoint(latitude=latitude, longitude=longitude)
result = gpx.get_nearest_locations(location_to_find_on_track)
self.assertTrue(len(result) == 1)
def test_positions_on_track_2(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
gpx.tracks.append(track)
location_to_find_on_track = None
# first segment:
segment = mod_gpx.GPXTrackSegment()
track.segments.append(segment)
for i in range(1000):
latitude = 45 + i * 0.001
longitude = 45 + i * 0.001
elevation = 100 + i * 2
point = mod_gpx.GPXTrackPoint(latitude=latitude, longitude=longitude, elevation=elevation)
segment.points.append(point)
if i == 500:
location_to_find_on_track = mod_gpx.GPXWaypoint(latitude=latitude, longitude=longitude)
# second segment
segment = mod_gpx.GPXTrackSegment()
track.segments.append(segment)
for i in range(1000):
latitude = 45.0000001 + i * 0.001
longitude = 45.0000001 + i * 0.001
elevation = 100 + i * 2
point = mod_gpx.GPXTrackPoint(latitude=latitude, longitude=longitude, elevation=elevation)
segment.points.append(point)
result = gpx.get_nearest_locations(location_to_find_on_track)
print('Found', result)
self.assertTrue(len(result) == 2)
def test_bounds(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
segment_1 = mod_gpx.GPXTrackSegment()
segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=-12, longitude=13))
segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=-100, longitude=-5))
segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=100, longitude=-13))
track.segments.append(segment_1)
segment_2 = mod_gpx.GPXTrackSegment()
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=-12, longitude=100))
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=-10, longitude=-5))
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=10, longitude=-100))
track.segments.append(segment_2)
gpx.tracks.append(track)
bounds = gpx.get_bounds()
self.assertEqual(bounds.min_latitude, -100)
self.assertEqual(bounds.max_latitude, 100)
self.assertEqual(bounds.min_longitude, -100)
self.assertEqual(bounds.max_longitude, 100)
# Test refresh bounds:
gpx.refresh_bounds()
self.assertEqual(gpx.bounds.min_latitude, -100)
self.assertEqual(gpx.bounds.max_latitude, 100)
self.assertEqual(gpx.bounds.min_longitude, -100)
self.assertEqual(gpx.bounds.max_longitude, 100)
def test_time_bounds(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
segment_1 = mod_gpx.GPXTrackSegment()
segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=-12, longitude=13))
segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=-100, longitude=-5, time=mod_datetime.datetime(2001, 1, 12)))
segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=100, longitude=-13, time=mod_datetime.datetime(2003, 1, 12)))
track.segments.append(segment_1)
segment_2 = mod_gpx.GPXTrackSegment()
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=-12, longitude=100, time=mod_datetime.datetime(2010, 1, 12)))
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=-10, longitude=-5, time=mod_datetime.datetime(2011, 1, 12)))
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=10, longitude=-100))
track.segments.append(segment_2)
gpx.tracks.append(track)
bounds = gpx.get_time_bounds()
self.assertEqual(bounds.start_time, mod_datetime.datetime(2001, 1, 12))
self.assertEqual(bounds.end_time, mod_datetime.datetime(2011, 1, 12))
def test_speed(self):
gpx = self.parse('track_with_speed.gpx')
gpx2 = self.reparse(gpx)
self.assertTrue(equals(gpx.waypoints, gpx2.waypoints))
self.assertTrue(equals(gpx.routes, gpx2.routes))
self.assertTrue(equals(gpx.tracks, gpx2.tracks))
self.assertTrue(equals(gpx, gpx2))
self.assertEqual(gpx.tracks[0].segments[0].points[0].speed, 1.2)
self.assertEqual(gpx.tracks[0].segments[0].points[1].speed, 2.2)
self.assertEqual(gpx.tracks[0].segments[0].points[2].speed, 3.2)
def test_dilutions(self):
gpx = self.parse('track_with_dilution_errors.gpx')
gpx2 = self.reparse(gpx)
self.assertTrue(equals(gpx.waypoints, gpx2.waypoints))
self.assertTrue(equals(gpx.routes, gpx2.routes))
self.assertTrue(equals(gpx.tracks, gpx2.tracks))
self.assertTrue(equals(gpx, gpx2))
for test_gpx in (gpx, gpx2):
self.assertTrue(test_gpx.waypoints[0].horizontal_dilution == 100.1)
self.assertTrue(test_gpx.waypoints[0].vertical_dilution == 101.1)
self.assertTrue(test_gpx.waypoints[0].position_dilution == 102.1)
self.assertTrue(test_gpx.routes[0].points[0].horizontal_dilution == 200.1)
self.assertTrue(test_gpx.routes[0].points[0].vertical_dilution == 201.1)
self.assertTrue(test_gpx.routes[0].points[0].position_dilution == 202.1)
self.assertTrue(test_gpx.tracks[0].segments[0].points[0].horizontal_dilution == 300.1)
self.assertTrue(test_gpx.tracks[0].segments[0].points[0].vertical_dilution == 301.1)
self.assertTrue(test_gpx.tracks[0].segments[0].points[0].position_dilution == 302.1)
def test_name_comment_and_symbol(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
gpx.tracks.append(track)
segment = mod_gpx.GPXTrackSegment()
track.segments.append(segment)
point = mod_gpx.GPXTrackPoint(12, 13, name='aaa', comment='ccc', symbol='sss')
segment.points.append(point)
xml = gpx.to_xml()
self.assertTrue('aaa' in xml)
gpx2 = self.reparse(gpx)
self.assertEqual(gpx2.tracks[0].segments[0].points[0].name, 'aaa')
self.assertEqual(gpx2.tracks[0].segments[0].points[0].comment, 'ccc')
self.assertEqual(gpx2.tracks[0].segments[0].points[0].symbol, 'sss')
def test_get_bounds_and_refresh_bounds(self):
gpx = mod_gpx.GPX()
latitudes = []
longitudes = []
for i in range(2):
track = mod_gpx.GPXTrack()
for i in range(2):
segment = mod_gpx.GPXTrackSegment()
for i in range(10):
latitude = 50. * (mod_random.random() - 0.5)
longitude = 50. * (mod_random.random() - 0.5)
point = mod_gpx.GPXTrackPoint(latitude=latitude, longitude=longitude)
segment.points.append(point)
latitudes.append(latitude)
longitudes.append(longitude)
track.segments.append(segment)
gpx.tracks.append(track)
bounds = gpx.get_bounds()
print(latitudes)
print(longitudes)
self.assertEqual(bounds.min_latitude, min(latitudes))
self.assertEqual(bounds.max_latitude, max(latitudes))
self.assertEqual(bounds.min_longitude, min(longitudes))
self.assertEqual(bounds.max_longitude, max(longitudes))
gpx.refresh_bounds()
self.assertEqual(gpx.bounds.min_latitude, min(latitudes))
self.assertEqual(gpx.bounds.max_latitude, max(latitudes))
self.assertEqual(gpx.bounds.min_longitude, min(longitudes))
self.assertEqual(gpx.bounds.max_longitude, max(longitudes))
def test_named_tuples_values_time_bounds(self):
gpx = self.parse('korita-zbevnica.gpx')
time_bounds = gpx.get_time_bounds()
start_time, end_time = gpx.get_time_bounds()
self.assertEqual(start_time, time_bounds.start_time)
self.assertEqual(end_time, time_bounds.end_time)
def test_named_tuples_values_moving_data(self):
gpx = self.parse('korita-zbevnica.gpx')
moving_data = gpx.get_moving_data()
moving_time, stopped_time, moving_distance, stopped_distance, max_speed = gpx.get_moving_data()
self.assertEqual(moving_time, moving_data.moving_time)
self.assertEqual(stopped_time, moving_data.stopped_time)
self.assertEqual(moving_distance, moving_data.moving_distance)
self.assertEqual(stopped_distance, moving_data.stopped_distance)
self.assertEqual(max_speed, moving_data.max_speed)
def test_named_tuples_values_uphill_downhill(self):
gpx = self.parse('korita-zbevnica.gpx')
uphill_downhill = gpx.get_uphill_downhill()
uphill, downhill = gpx.get_uphill_downhill()
self.assertEqual(uphill, uphill_downhill.uphill)
self.assertEqual(downhill, uphill_downhill.downhill)
def test_named_tuples_values_elevation_extremes(self):
gpx = self.parse('korita-zbevnica.gpx')
elevation_extremes = gpx.get_elevation_extremes()
minimum, maximum = gpx.get_elevation_extremes()
self.assertEqual(minimum, elevation_extremes.minimum)
self.assertEqual(maximum, elevation_extremes.maximum)
def test_named_tuples_values_nearest_location_data(self):
gpx = self.parse('korita-zbevnica.gpx')
location = gpx.tracks[1].segments[0].points[2]
location.latitude *= 1.00001
location.longitude *= 0.99999
nearest_location_data = gpx.get_nearest_location(location)
found_location, track_no, segment_no, point_no = gpx.get_nearest_location(location)
self.assertEqual(found_location, nearest_location_data.location)
self.assertEqual(track_no, nearest_location_data.track_no)
self.assertEqual(segment_no, nearest_location_data.segment_no)
self.assertEqual(point_no, nearest_location_data.point_no)
def test_named_tuples_values_point_data(self):
gpx = self.parse('korita-zbevnica.gpx')
points_datas = gpx.get_points_data()
for point_data in points_datas:
point, distance_from_start, track_no, segment_no, point_no = point_data
self.assertEqual(point, point_data.point)
self.assertEqual(distance_from_start, point_data.distance_from_start)
self.assertEqual(track_no, point_data.track_no)
self.assertEqual(segment_no, point_data.segment_no)
self.assertEqual(point_no, point_data.point_no)
def test_track_points_data(self):
gpx = self.parse('korita-zbevnica.gpx')
points_data_2d = gpx.get_points_data(distance_2d=True)
point, distance_from_start, track_no, segment_no, point_no = points_data_2d[-1]
self.assertEqual(track_no, len(gpx.tracks) - 1)
self.assertEqual(segment_no, len(gpx.tracks[-1].segments) - 1)
self.assertEqual(point_no, len(gpx.tracks[-1].segments[-1].points) - 1)
self.assertTrue(abs(distance_from_start - gpx.length_2d()) < 0.0001)
points_data_3d = gpx.get_points_data(distance_2d=False)
point, distance_from_start, track_no, segment_no, point_no = points_data_3d[-1]
self.assertEqual(track_no, len(gpx.tracks) - 1)
self.assertEqual(segment_no, len(gpx.tracks[-1].segments) - 1)
self.assertEqual(point_no, len(gpx.tracks[-1].segments[-1].points) - 1)
self.assertTrue(abs(distance_from_start - gpx.length_3d()) < 0.0001)
self.assertTrue(gpx.length_2d() != gpx.length_3d())
def test_walk_route_points(self):
with open('test_files/route.gpx') as f:
gpx = mod_gpxpy.parse(f)
for point in gpx.routes[0].walk(only_points=True):
self.assertTrue(point)
for point, point_no in gpx.routes[0].walk():
self.assertTrue(point)
self.assertEqual(point_no, len(gpx.routes[0].points) - 1)
def test_walk_gpx_points(self):
gpx = self.parse('korita-zbevnica.gpx')
for point in gpx.walk():
self.assertTrue(point)
for point, track_no, segment_no, point_no in gpx.walk():
self.assertTrue(point)
self.assertEqual(track_no, len(gpx.tracks) - 1)
self.assertEqual(segment_no, len(gpx.tracks[-1].segments) - 1)
self.assertEqual(point_no, len(gpx.tracks[-1].segments[-1].points) - 1)
def test_walk_gpx_points2(self):
gpx = self.parse('korita-zbevnica.gpx')
track = gpx.tracks[1]
for point in track.walk():
self.assertTrue(point)
for point, segment_no, point_no in track.walk():
self.assertTrue(point)
self.assertEqual(segment_no, len(track.segments) - 1)
self.assertEqual(point_no, len(track.segments[-1].points) - 1)
def test_walk_segment_points(self):
gpx = self.parse('korita-zbevnica.gpx')
track = gpx.tracks[1]
segment = track.segments[0]
assert len(segment.points) > 0
for point in segment.walk():
self.assertTrue(point)
"""
for point, segment_no, point_no in track.walk():
self.assertTrue(point)
self.assertEqual(segment_no, len(track.segments) - 1)
self.assertEqual(point_no, len(track.segments[-1].points) - 1)
"""
def test_angle_0(self):
loc1 = mod_geo.Location(0, 0)
loc2 = mod_geo.Location(0, 1)
loc1.elevation = 100
loc2.elevation = 100
angle_radians = mod_geo.elevation_angle(loc1, loc2, radians=True)
angle_degrees = mod_geo.elevation_angle(loc1, loc2, radians=False)
self.assertEqual(angle_radians, 0)
self.assertEqual(angle_degrees, 0)
def test_angle(self):
loc1 = mod_geo.Location(0, 0)
loc2 = mod_geo.Location(0, 1)
loc1.elevation = 100
loc2.elevation = loc1.elevation + loc1.distance_2d(loc2)
angle_radians = mod_geo.elevation_angle(loc1, loc2, radians=True)
angle_degrees = mod_geo.elevation_angle(loc1, loc2, radians=False)
self.assertEqual(angle_radians, mod_math.pi / 4)
self.assertEqual(angle_degrees, 45)
def test_angle_2(self):
loc1 = mod_geo.Location(45, 45)
loc2 = mod_geo.Location(46, 45)
loc1.elevation = 100
loc2.elevation = loc1.elevation + 0.5 * loc1.distance_2d(loc2)
angle_radians = mod_geo.elevation_angle(loc1, loc2, radians=True)
angle_degrees = mod_geo.elevation_angle(loc1, loc2, radians=False)
self.assertTrue(angle_radians < mod_math.pi / 4)
self.assertTrue(angle_degrees < 45)
def test_angle_3(self):
loc1 = mod_geo.Location(45, 45)
loc2 = mod_geo.Location(46, 45)
loc1.elevation = 100
loc2.elevation = loc1.elevation + 1.5 * loc1.distance_2d(loc2)
angle_radians = mod_geo.elevation_angle(loc1, loc2, radians=True)
angle_degrees = mod_geo.elevation_angle(loc1, loc2, radians=False)
self.assertTrue(angle_radians > mod_math.pi / 4)
self.assertTrue(angle_degrees > 45)
def test_angle_4(self):
loc1 = mod_geo.Location(45, 45)
loc2 = mod_geo.Location(46, 45)
loc1.elevation = 100
loc2.elevation = loc1.elevation - loc1.distance_2d(loc2)
angle_radians = mod_geo.elevation_angle(loc1, loc2, radians=True)
angle_degrees = mod_geo.elevation_angle(loc1, loc2, radians=False)
self.assertEqual(angle_radians, - mod_math.pi / 4)
self.assertEqual(angle_degrees, - 45)
def test_angle_loc(self):
loc1 = mod_geo.Location(45, 45)
loc2 = mod_geo.Location(46, 45)
self.assertEqual(loc1.elevation_angle(loc2), mod_geo.elevation_angle(loc1, loc2))
self.assertEqual(loc1.elevation_angle(loc2, radians=True), mod_geo.elevation_angle(loc1, loc2, radians=True))
self.assertEqual(loc1.elevation_angle(loc2, radians=False), mod_geo.elevation_angle(loc1, loc2, radians=False))
def test_ignore_maximums_for_max_speed(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
gpx.tracks.append(track)
tmp_time = mod_datetime.datetime.now()
tmp_longitude = 0
segment_1 = mod_gpx.GPXTrackSegment()
for i in range(4):
segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=tmp_longitude, time=tmp_time))
tmp_longitude += 0.01
tmp_time += mod_datetime.timedelta(hours=1)
track.segments.append(segment_1)
moving_time, stopped_time, moving_distance, stopped_distance, max_speed_with_too_small_segment = gpx.get_moving_data()
# Too few points:
mod_logging.debug('max_speed = %s', max_speed_with_too_small_segment)
self.assertFalse(max_speed_with_too_small_segment)
tmp_longitude = 0.
segment_2 = mod_gpx.GPXTrackSegment()
for i in range(55):
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=tmp_longitude, time=tmp_time))
tmp_longitude += 0.01
tmp_time += mod_datetime.timedelta(hours=1)
track.segments.append(segment_2)
moving_time, stopped_time, moving_distance, stopped_distance, max_speed_with_equal_speeds = gpx.get_moving_data()
mod_logging.debug('max_speed = %s', max_speed_with_equal_speeds)
self.assertTrue(max_speed_with_equal_speeds > 0)
# When we add too few extremes, they should be ignored:
for i in range(10):
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=tmp_longitude, time=tmp_time))
tmp_longitude += 0.7
tmp_time += mod_datetime.timedelta(hours=1)
moving_time, stopped_time, moving_distance, stopped_distance, max_speed_with_extreemes = gpx.get_moving_data()
self.assertTrue(abs(max_speed_with_extreemes - max_speed_with_equal_speeds) < 0.001)
# But if there are many extremes (they are no more extremes):
for i in range(100):
# Sometimes add on start, sometimes on end:
if i % 2 == 0:
segment_2.points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=tmp_longitude, time=tmp_time))
else:
segment_2.points.insert(0, mod_gpx.GPXTrackPoint(latitude=0, longitude=tmp_longitude, time=tmp_time))
tmp_longitude += 0.5
tmp_time += mod_datetime.timedelta(hours=1)
moving_time, stopped_time, moving_distance, stopped_distance, max_speed_with_more_extreemes = gpx.get_moving_data()
mod_logging.debug('max_speed_with_more_extreemes = %s', max_speed_with_more_extreemes)
mod_logging.debug('max_speed_with_extreemes = %s', max_speed_with_extreemes)
self.assertTrue(max_speed_with_more_extreemes - max_speed_with_extreemes > 10)
def test_track_with_elevation_zero(self):
with open('test_files/cerknicko-jezero-with-elevations-zero.gpx') as f:
gpx = mod_gpxpy.parse(f)
minimum, maximum = gpx.get_elevation_extremes()
self.assertEqual(minimum, 0)
self.assertEqual(maximum, 0)
uphill, downhill = gpx.get_uphill_downhill()
self.assertEqual(uphill, 0)
self.assertEqual(downhill, 0)
def test_track_without_elevation(self):
with open('test_files/cerknicko-jezero-without-elevations.gpx') as f:
gpx = mod_gpxpy.parse(f)
minimum, maximum = gpx.get_elevation_extremes()
self.assertEqual(minimum, None)
self.assertEqual(maximum, None)
uphill, downhill = gpx.get_uphill_downhill()
self.assertEqual(uphill, 0)
self.assertEqual(downhill, 0)
def test_has_elevation_false(self):
with open('test_files/cerknicko-jezero-without-elevations.gpx') as f:
gpx = mod_gpxpy.parse(f)
self.assertFalse(gpx.has_elevations())
def test_has_elevation_true(self):
with open('test_files/cerknicko-jezero.gpx') as f:
gpx = mod_gpxpy.parse(f)
self.assertFalse(gpx.has_elevations())
def test_track_with_some_points_are_without_elevations(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
gpx.tracks.append(track)
tmp_latlong = 0
segment_1 = mod_gpx.GPXTrackSegment()
for i in range(4):
point = mod_gpx.GPXTrackPoint(latitude=tmp_latlong, longitude=tmp_latlong)
segment_1.points.append(point)
if i % 3 == 0:
point.elevation = None
else:
point.elevation = 100 / (i + 1)
track.segments.append(segment_1)
minimum, maximum = gpx.get_elevation_extremes()
self.assertTrue(minimum is not None)
self.assertTrue(maximum is not None)
uphill, downhill = gpx.get_uphill_downhill()
self.assertTrue(uphill is not None)
self.assertTrue(downhill is not None)
def test_track_with_empty_segment(self):
with open('test_files/track-with-empty-segment.gpx') as f:
gpx = mod_gpxpy.parse(f)
self.assertIsNotNone(gpx.tracks[0].get_bounds().min_latitude)
self.assertIsNotNone(gpx.tracks[0].get_bounds().min_longitude)
def test_add_missing_data_no_intervals(self):
# Test only that the add_missing_function is called with the right data
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13,
elevation=10))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=14,
elevation=100))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=15,
elevation=20))
# Shouldn't be called because all points have elevation
def _add_missing_function(interval, start_point, end_point, ratios):
raise Exception()
gpx.add_missing_data(get_data_function=lambda point: point.elevation,
add_missing_function=_add_missing_function)
def test_add_missing_data_one_interval(self):
# Test only that the add_missing_function is called with the right data
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13,
elevation=10))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=14,
elevation=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=15,
elevation=20))
# Shouldn't be called because all points have elevation
def _add_missing_function(interval, start_point, end_point, ratios):
assert start_point
assert start_point.latitude == 12 and start_point.longitude == 13
assert end_point
assert end_point.latitude == 12 and end_point.longitude == 15
assert len(interval) == 1
assert interval[0].latitude == 12 and interval[0].longitude == 14
assert ratios
interval[0].elevation = 314
gpx.add_missing_data(get_data_function=lambda point: point.elevation,
add_missing_function=_add_missing_function)
self.assertEqual(314, gpx.tracks[0].segments[0].points[1].elevation)
def test_add_missing_data_one_interval_and_empty_points_on_start_and_end(self):
# Test only that the add_missing_function is called with the right data
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13,
elevation=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13,
elevation=10))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=14,
elevation=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=15,
elevation=20))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13,
elevation=None))
# Shouldn't be called because all points have elevation
def _add_missing_function(interval, start_point, end_point, ratios):
assert start_point
assert start_point.latitude == 12 and start_point.longitude == 13
assert end_point
assert end_point.latitude == 12 and end_point.longitude == 15
assert len(interval) == 1
assert interval[0].latitude == 12 and interval[0].longitude == 14
assert ratios
interval[0].elevation = 314
gpx.add_missing_data(get_data_function=lambda point: point.elevation,
add_missing_function=_add_missing_function)
# Points at start and end should not have elevation 314 because have
# no two bounding points with elevations:
self.assertEqual(None, gpx.tracks[0].segments[0].points[0].elevation)
self.assertEqual(None, gpx.tracks[0].segments[0].points[-1].elevation)
self.assertEqual(314, gpx.tracks[0].segments[0].points[2].elevation)
def test_add_missing_speeds(self):
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=0,
time=mod_datetime.datetime(2013, 1, 2, 12, 0),
speed=0))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=0.00899, # 1 km/h over 1 km
time=mod_datetime.datetime(2013, 1, 2, 13, 0)))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=0.02697, # 2 km/h over 2 km
time=mod_datetime.datetime(2013, 1, 2, 14, 0)))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=0.03596, # 3 km/h over 1 km
time=mod_datetime.datetime(2013, 1, 2, 14, 20)))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=0, longitude=0.06293, # 9 km/h over 3 km
time=mod_datetime.datetime(2013, 1, 2, 14, 40),
speed=0))
gpx.add_missing_speeds()
self.assertTrue(abs(3000./(2*3600) - gpx.tracks[0].segments[0].points[1].speed) < 0.01)
self.assertTrue(abs(3000./(80*60) - gpx.tracks[0].segments[0].points[2].speed) < 0.01)
self.assertTrue(abs(4000./(40*60) - gpx.tracks[0].segments[0].points[3].speed) < 0.01)
def test_add_missing_elevations(self):
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13, longitude=12,
elevation=10))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.25, longitude=12,
elevation=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.5, longitude=12,
elevation=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.9, longitude=12,
elevation=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=14, longitude=12,
elevation=20))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=15, longitude=12,
elevation=None))
gpx.add_missing_elevations()
self.assertTrue(abs(12.5 - gpx.tracks[0].segments[0].points[1].elevation) < 0.01)
self.assertTrue(abs(15 - gpx.tracks[0].segments[0].points[2].elevation) < 0.01)
self.assertTrue(abs(19 - gpx.tracks[0].segments[0].points[3].elevation) < 0.01)
def test_add_missing_elevations_without_ele(self):
xml = """
0.0
"""
gpx = mod_gpxpy.parse(xml)
gpx.add_missing_elevations()
self.assertTrue(gpx.tracks[0].segments[0].points[0].elevation == None)
self.assertTrue(gpx.tracks[0].segments[0].points[1].elevation == None)
self.assertTrue(gpx.tracks[0].segments[0].points[2].elevation == 0.0)
def test_add_missing_times(self):
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13, longitude=12,
time=mod_datetime.datetime(2013, 1, 2, 12, 0)))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.25, longitude=12,
time=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.5, longitude=12,
time=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.75, longitude=12,
time=None))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=14, longitude=12,
time=mod_datetime.datetime(2013, 1, 2, 13, 0)))
gpx.add_missing_times()
time_1 = gpx.tracks[0].segments[0].points[1].time
time_2 = gpx.tracks[0].segments[0].points[2].time
time_3 = gpx.tracks[0].segments[0].points[3].time
self.assertEqual(2013, time_1.year)
self.assertEqual(1, time_1.month)
self.assertEqual(2, time_1.day)
self.assertEqual(12, time_1.hour)
self.assertEqual(15, time_1.minute)
self.assertEqual(2013, time_2.year)
self.assertEqual(1, time_2.month)
self.assertEqual(2, time_2.day)
self.assertEqual(12, time_2.hour)
self.assertEqual(30, time_2.minute)
self.assertEqual(2013, time_3.year)
self.assertEqual(1, time_3.month)
self.assertEqual(2, time_3.day)
self.assertEqual(12, time_3.hour)
self.assertEqual(45, time_3.minute)
def test_add_missing_times_2(self):
xml = ''
xml += '\n'
xml += '\n'
xml += '\n'
xml += '\n'
xml += '\n'
xml += '\n'
xml += '\n'
xml += '18\n'
xml += '\n'
gpx = mod_gpxpy.parse(xml)
gpx.add_missing_times()
previous_time = None
for point in gpx.walk(only_points=True):
if point.time:
if previous_time:
print('point.time=', point.time, 'previous_time=', previous_time)
self.assertTrue(point.time > previous_time)
previous_time = point.time
def test_distance_from_line(self):
d = mod_geo.distance_from_line(mod_geo.Location(1, 1),
mod_geo.Location(0, -1),
mod_geo.Location(0, 1))
self.assertTrue(abs(d - mod_geo.ONE_DEGREE) < 100)
def test_simplify(self):
for gpx_file in mod_os.listdir('test_files'):
print('Parsing:', gpx_file)
with custom_open('test_files/%s' % gpx_file, encoding='utf-8')as f:
gpx = mod_gpxpy.parse(f)
length_2d_original = gpx.length_2d()
with custom_open('test_files/%s' % gpx_file, encoding='utf-8') as f:
gpx = mod_gpxpy.parse(f)
gpx.simplify(max_distance=50)
length_2d_after_distance_50 = gpx.length_2d()
with custom_open('test_files/%s' % gpx_file, encoding='utf-8') as f:
gpx = mod_gpxpy.parse(f)
gpx.simplify(max_distance=10)
length_2d_after_distance_10 = gpx.length_2d()
print(length_2d_original, length_2d_after_distance_10, length_2d_after_distance_50)
# When simplifying the resulting distance should always be less than the original:
self.assertTrue(length_2d_original >= length_2d_after_distance_10)
self.assertTrue(length_2d_original >= length_2d_after_distance_50)
# Simplify with bigger max_distance and => bigger error from original
self.assertTrue(length_2d_after_distance_10 >= length_2d_after_distance_50)
# The resulting distance usually shouldn't be too different from
# the original (here check for 80% and 70%)
self.assertTrue(length_2d_after_distance_10 >= length_2d_original * .6)
self.assertTrue(length_2d_after_distance_50 >= length_2d_original * .5)
def test_simplify_circular_gpx(self):
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13, longitude=12))
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.25, longitude=12))
# Then the first point again:
gpx.tracks[0].segments[0].points.append(gpx.tracks[0].segments[0].points[0])
gpx.simplify()
def test_nan_elevation(self):
xml = ' nan nan nan'
gpx = mod_gpxpy.parse(xml)
self.assertTrue(mod_math.isnan(gpx.tracks[0].segments[0].points[0].elevation))
self.assertTrue(mod_math.isnan(gpx.routes[0].points[0].elevation))
self.assertTrue(mod_math.isnan(gpx.waypoints[0].elevation))
def test_time_difference(self):
point_1 = mod_gpx.GPXTrackPoint(latitude=13, longitude=12,
time=mod_datetime.datetime(2013, 1, 2, 12, 31))
point_2 = mod_gpx.GPXTrackPoint(latitude=13, longitude=12,
time=mod_datetime.datetime(2013, 1, 3, 12, 32))
seconds = point_1.time_difference(point_2)
self.assertEqual(seconds, 60 * 60 * 24 + 60)
def test_parse_time(self):
timestamps = [
'2001-10-26T21:32:52',
#'2001-10-26T21:32:52+0200',
'2001-10-26T19:32:52Z',
#'2001-10-26T19:32:52+00:00',
#'-2001-10-26T21:32:52',
'2001-10-26T21:32:52.12679',
'2001-10-26T21:32:52',
#'2001-10-26T21:32:52+02:00',
'2001-10-26T19:32:52Z',
#'2001-10-26T19:32:52+00:00',
#'-2001-10-26T21:32:52',
'2001-10-26T21:32:52.12679',
]
timestamps_without_tz = list(map(lambda x: x.replace('T', ' ').replace('Z', ''), timestamps))
for t in timestamps_without_tz:
timestamps.append(t)
for timestamp in timestamps:
print('Parsing: %s' % timestamp)
self.assertTrue(mod_gpxfield.parse_time(timestamp) is not None)
def test_get_location_at(self):
gpx = mod_gpx.GPX()
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
p0 = mod_gpx.GPXTrackPoint(latitude=13.0, longitude=13.0, time=mod_datetime.datetime(2013, 1, 2, 12, 30, 0))
p1 = mod_gpx.GPXTrackPoint(latitude=13.1, longitude=13.1, time=mod_datetime.datetime(2013, 1, 2, 12, 31, 0))
gpx.tracks[0].segments[0].points.append(p0)
gpx.tracks[0].segments[0].points.append(p1)
self.assertEqual(gpx.tracks[0].get_location_at(mod_datetime.datetime(2013, 1, 2, 12, 29, 30)), [])
self.assertEqual(gpx.tracks[0].get_location_at(mod_datetime.datetime(2013, 1, 2, 12, 30, 0))[0], p0)
self.assertEqual(gpx.tracks[0].get_location_at(mod_datetime.datetime(2013, 1, 2, 12, 30, 30))[0], p1)
self.assertEqual(gpx.tracks[0].get_location_at(mod_datetime.datetime(2013, 1, 2, 12, 31, 0))[0], p1)
self.assertEqual(gpx.tracks[0].get_location_at(mod_datetime.datetime(2013, 1, 2, 12, 31, 30)), [])
def test_adjust_time_tracks_only(self):
gpx = mod_gpx.GPX()
t0 = mod_datetime.datetime(2013, 1, 2, 12, 30, 0)
t1 = mod_datetime.datetime(2013, 1, 2, 12, 31, 0)
t0_adjusted = t0 + mod_datetime.timedelta(seconds=1)
t1_adjusted = t1 + mod_datetime.timedelta(seconds=1)
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
p0 = mod_gpx.GPXTrackPoint(latitude=13.0, longitude=13.0)
p1 = mod_gpx.GPXTrackPoint(latitude=13.1, longitude=13.1)
gpx.tracks[0].segments[0].points.append(p0)
gpx.tracks[0].segments[0].points.append(p1)
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
p0 = mod_gpx.GPXTrackPoint(latitude=13.0, longitude=13.0, time=t0)
p1 = mod_gpx.GPXTrackPoint(latitude=13.1, longitude=13.1, time=t1)
gpx.tracks[0].segments[1].points.append(p0)
gpx.tracks[0].segments[1].points.append(p1)
gpx.waypoints.append(mod_gpx.GPXWaypoint(latitude=13.0, longitude=13.0))
gpx.waypoints.append(mod_gpx.GPXWaypoint(latitude=13.1, longitude=13.1, time=t0))
d1 = mod_datetime.timedelta(-1, -1)
d2 = mod_datetime.timedelta(1, 2)
# move back and forward to add a total of 1 second
gpx.adjust_time(d1)
gpx.adjust_time(d2)
self.assertEqual(gpx.tracks[0].segments[0].points[0].time, None)
self.assertEqual(gpx.tracks[0].segments[0].points[1].time, None)
self.assertEqual(gpx.tracks[0].segments[1].points[0].time, t0_adjusted)
self.assertEqual(gpx.tracks[0].segments[1].points[1].time, t1_adjusted)
self.assertEqual(gpx.waypoints[0].time, None)
self.assertEqual(gpx.waypoints[1].time, t0)
def test_adjust_time_all(self):
gpx = mod_gpx.GPX()
t0 = mod_datetime.datetime(2018, 7, 15, 12, 30, 0)
t1 = mod_datetime.datetime(2018, 7, 15, 12, 31, 0)
t0_adjusted = t0 + mod_datetime.timedelta(seconds=1)
t1_adjusted = t1 + mod_datetime.timedelta(seconds=1)
gpx.waypoints.append(mod_gpx.GPXWaypoint(latitude=13.0, longitude=13.0))
gpx.waypoints.append(mod_gpx.GPXWaypoint(latitude=13.1, longitude=13.1, time=t0))
gpx.routes.append(mod_gpx.GPXRoute())
p0 = mod_gpx.GPXRoutePoint(latitude=13.0, longitude=13.0)
p1 = mod_gpx.GPXRoutePoint(latitude=13.1, longitude=13.1)
gpx.routes[0].points.append(p0)
gpx.routes[0].points.append(p1)
gpx.routes.append(mod_gpx.GPXRoute())
p0 = mod_gpx.GPXRoutePoint(latitude=13.0, longitude=13.0, time=t0)
p1 = mod_gpx.GPXRoutePoint(latitude=13.1, longitude=13.1, time=t1)
gpx.routes[1].points.append(p0)
gpx.routes[1].points.append(p1)
d1 = mod_datetime.timedelta(-1, -1)
d2 = mod_datetime.timedelta(1, 2)
# move back and forward to add a total of 1 second
gpx.adjust_time(d1, all=True)
gpx.adjust_time(d2, all=True)
self.assertEqual(gpx.waypoints[0].time, None)
self.assertEqual(gpx.waypoints[1].time, t0_adjusted)
self.assertEqual(gpx.routes[0].points[0].time, None)
self.assertEqual(gpx.routes[0].points[1].time, None)
self.assertEqual(gpx.routes[1].points[0].time, t0_adjusted)
self.assertEqual(gpx.routes[1].points[1].time, t1_adjusted)
def test_unicode(self):
with custom_open('test_files/unicode2.gpx', encoding='utf-8') as f:
parser = mod_parser.GPXParser(f)
gpx = parser.parse()
gpx.to_xml()
def test_location_delta(self):
location = mod_geo.Location(-20, -50)
location_2 = location + mod_geo.LocationDelta(angle=45, distance=100)
self.assertTrue(cca(location_2.latitude - location.latitude, location_2.longitude - location.longitude))
def test_location_equator_delta_distance_111120(self):
self.__test_location_delta(mod_geo.Location(0, 13), 111120)
def test_location_equator_delta_distance_50(self):
self.__test_location_delta(mod_geo.Location(0, -50), 50)
def test_location_nonequator_delta_distance_111120(self):
self.__test_location_delta(mod_geo.Location(45, 13), 111120)
def test_location_nonequator_delta_distance_50(self):
self.__test_location_delta(mod_geo.Location(-20, -50), 50)
def test_delta_add_and_move(self):
location = mod_geo.Location(45.1, 13.2)
delta = mod_geo.LocationDelta(angle=20, distance=1000)
location_2 = location + delta
location.move(delta)
self.assertTrue(cca(location.latitude, location_2.latitude))
self.assertTrue(cca(location.longitude, location_2.longitude))
def test_parse_gpx_with_node_with_comments(self):
with open('test_files/gpx-with-node-with-comments.gpx') as f:
self.assertTrue(mod_gpxpy.parse(f))
def __test_location_delta(self, location, distance):
angles = [ x * 15 for x in range(int(360 / 15)) ]
print(angles)
previous_location = None
distances_between_points = []
for angle in angles:
new_location = location + mod_geo.LocationDelta(angle=angle, distance=distance)
# All locations same distance from center
self.assertTrue(cca(location.distance_2d(new_location), distance))
if previous_location:
distances_between_points.append(new_location.distance_2d(previous_location))
previous_location = new_location
print(distances_between_points)
# All points should be equidistant on a circle:
for i in range(1, len(distances_between_points)):
self.assertTrue(cca(distances_between_points[0], distances_between_points[i]))
def test_gpx_10_fields(self):
""" Test (de) serialization all gpx1.0 fields """
with open('test_files/gpx1.0_with_all_fields.gpx') as f:
xml = f.read()
original_gpx = mod_gpxpy.parse(xml)
# Serialize and parse again to be sure that all is preserved:
reparsed_gpx = mod_gpxpy.parse(original_gpx.to_xml())
original_dom = mod_minidom.parseString(xml)
reparsed_dom = mod_minidom.parseString(reparsed_gpx.to_xml())
# Validated with SAXParser in "make test"
with open('test_files/validation_gpx10.gpx', 'w') as f:
f.write(reparsed_gpx.to_xml())
for gpx in (original_gpx, reparsed_gpx):
for dom in (original_dom, reparsed_dom):
self.assertEqual(gpx.version, '1.0')
self.assertEqual(get_dom_node(dom, 'gpx').attributes['version'].nodeValue, '1.0')
self.assertEqual(gpx.creator, '...')
self.assertEqual(get_dom_node(dom, 'gpx').attributes['creator'].nodeValue, '...')
self.assertEqual(gpx.name, 'example name')
self.assertEqual(get_dom_node(dom, 'gpx/name').firstChild.nodeValue, 'example name')
self.assertEqual(gpx.description, 'example description')
self.assertEqual(get_dom_node(dom, 'gpx/desc').firstChild.nodeValue, 'example description')
self.assertEqual(gpx.author_name, 'example author')
self.assertEqual(get_dom_node(dom, 'gpx/author').firstChild.nodeValue, 'example author')
self.assertEqual(gpx.author_email, 'example@email.com')
self.assertEqual(get_dom_node(dom, 'gpx/email').firstChild.nodeValue, 'example@email.com')
self.assertEqual(gpx.link, 'http://example.url')
self.assertEqual(get_dom_node(dom, 'gpx/url').firstChild.nodeValue, 'http://example.url')
self.assertEqual(gpx.link_text, 'example urlname')
self.assertEqual(get_dom_node(dom, 'gpx/urlname').firstChild.nodeValue, 'example urlname')
self.assertEqual(gpx.time, mod_datetime.datetime(2013, 1, 1, 12, 0, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertTrue(get_dom_node(dom, 'gpx/time').firstChild.nodeValue in ('2013-01-01T12:00:00Z', '2013-01-01T12:00:00'))
self.assertEqual(gpx.keywords, 'example keywords')
self.assertEqual(get_dom_node(dom, 'gpx/keywords').firstChild.nodeValue, 'example keywords')
self.assertEqual(gpx.bounds.min_latitude, 1.2)
self.assertEqual(get_dom_node(dom, 'gpx/bounds').attributes['minlat'].value, '1.2')
# Waypoints:
self.assertEqual(len(gpx.waypoints), 2)
self.assertEqual(gpx.waypoints[0].latitude, 12.3)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]').attributes['lat'].value, '12.3')
self.assertEqual(gpx.waypoints[0].longitude, 45.6)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]').attributes['lon'].value, '45.6')
self.assertEqual(gpx.waypoints[0].longitude, 45.6)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]').attributes['lon'].value, '45.6')
self.assertEqual(gpx.waypoints[0].elevation, 75.1)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/ele').firstChild.nodeValue, '75.1')
self.assertEqual(gpx.waypoints[0].time, mod_datetime.datetime(2013, 1, 2, 2, 3, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/time').firstChild.nodeValue, '2013-01-02T02:03:00Z')
self.assertEqual(gpx.waypoints[0].magnetic_variation, 1.1)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/magvar').firstChild.nodeValue, '1.1')
self.assertEqual(gpx.waypoints[0].geoid_height, 2.0)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/geoidheight').firstChild.nodeValue, '2.0')
self.assertEqual(gpx.waypoints[0].name, 'example name')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/name').firstChild.nodeValue, 'example name')
self.assertEqual(gpx.waypoints[0].comment, 'example cmt')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/cmt').firstChild.nodeValue, 'example cmt')
self.assertEqual(gpx.waypoints[0].description, 'example desc')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/desc').firstChild.nodeValue, 'example desc')
self.assertEqual(gpx.waypoints[0].source, 'example src')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/src').firstChild.nodeValue, 'example src')
self.assertEqual(gpx.waypoints[0].link, 'example url')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/url').firstChild.nodeValue, 'example url')
self.assertEqual(gpx.waypoints[0].link_text, 'example urlname')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/urlname').firstChild.nodeValue, 'example urlname')
self.assertEqual(gpx.waypoints[1].latitude, 13.4)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[1]').attributes['lat'].value, '13.4')
self.assertEqual(gpx.waypoints[1].longitude, 46.7)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[1]').attributes['lon'].value, '46.7')
self.assertEqual(len(gpx.routes), 2)
self.assertEqual(gpx.routes[0].name, 'example name')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/name').firstChild.nodeValue, 'example name')
self.assertEqual(gpx.routes[0].comment, 'example cmt')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/cmt').firstChild.nodeValue, 'example cmt')
self.assertEqual(gpx.routes[0].description, 'example desc')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/desc').firstChild.nodeValue, 'example desc')
self.assertEqual(gpx.routes[0].source, 'example src')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/src').firstChild.nodeValue, 'example src')
self.assertEqual(gpx.routes[0].link, 'example url')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/url').firstChild.nodeValue, 'example url')
# Rte pt:
self.assertEqual(gpx.routes[0].points[0].latitude, 10)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]').attributes['lat'].value in ('10.0', '10'))
self.assertEqual(gpx.routes[0].points[0].longitude, 20)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]').attributes['lon'].value in ('20.0', '20'))
self.assertEqual(gpx.routes[0].points[0].elevation, 75.1)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/ele').firstChild.nodeValue, '75.1')
self.assertEqual(gpx.routes[0].points[0].time, mod_datetime.datetime(2013, 1, 2, 2, 3, 3, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/time').firstChild.nodeValue, '2013-01-02T02:03:03Z')
self.assertEqual(gpx.routes[0].points[0].magnetic_variation, 1.2)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/magvar').firstChild.nodeValue, '1.2')
self.assertEqual(gpx.routes[0].points[0].geoid_height, 2.1)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/geoidheight').firstChild.nodeValue, '2.1')
self.assertEqual(gpx.routes[0].points[0].name, 'example name r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/name').firstChild.nodeValue, 'example name r')
self.assertEqual(gpx.routes[0].points[0].comment, 'example cmt r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/cmt').firstChild.nodeValue, 'example cmt r')
self.assertEqual(gpx.routes[0].points[0].description, 'example desc r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/desc').firstChild.nodeValue, 'example desc r')
self.assertEqual(gpx.routes[0].points[0].source, 'example src r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/src').firstChild.nodeValue, 'example src r')
self.assertEqual(gpx.routes[0].points[0].link, 'example url r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/url').firstChild.nodeValue, 'example url r')
self.assertEqual(gpx.routes[0].points[0].link_text, 'example urlname r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/urlname').firstChild.nodeValue, 'example urlname r')
self.assertEqual(gpx.routes[0].points[0].symbol, 'example sym r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/sym').firstChild.nodeValue, 'example sym r')
self.assertEqual(gpx.routes[0].points[0].type, 'example type r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/type').firstChild.nodeValue, 'example type r')
self.assertEqual(gpx.routes[0].points[0].type_of_gpx_fix, '3d')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/fix').firstChild.nodeValue, '3d')
self.assertEqual(gpx.routes[0].points[0].satellites, 6)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/sat').firstChild.nodeValue, '6')
self.assertEqual(gpx.routes[0].points[0].vertical_dilution, 8)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/vdop').firstChild.nodeValue in ('8.0', '8'))
self.assertEqual(gpx.routes[0].points[0].horizontal_dilution, 7)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/hdop').firstChild.nodeValue in ('7.0', '7'))
self.assertEqual(gpx.routes[0].points[0].position_dilution, 9)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/pdop').firstChild.nodeValue in ('9.0', '9'))
self.assertEqual(gpx.routes[0].points[0].age_of_dgps_data, 10)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/ageofdgpsdata').firstChild.nodeValue in ('10.0', '10'))
self.assertEqual(gpx.routes[0].points[0].dgps_id, '99')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/dgpsid').firstChild.nodeValue, '99')
# second rtept:
self.assertEqual(gpx.routes[0].points[1].latitude, 11)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[1]').attributes['lat'].value in ('11.0', '11'))
self.assertEqual(gpx.routes[0].points[1].longitude, 21)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[1]').attributes['lon'].value in ('21.0', '21'))
# Rte
self.assertEqual(gpx.routes[1].name, 'second route')
self.assertEqual(get_dom_node(dom, 'gpx/rte[1]/name').firstChild.nodeValue, 'second route')
self.assertEqual(gpx.routes[1].description, 'example desc 2')
self.assertEqual(get_dom_node(dom, 'gpx/rte[1]/desc').firstChild.nodeValue, 'example desc 2')
self.assertEqual(gpx.routes[0].link_text, 'example urlname')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/urlname').firstChild.nodeValue, 'example urlname')
self.assertEqual(gpx.routes[0].number, 7)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/number').firstChild.nodeValue, '7')
self.assertEqual(len(gpx.routes[0].points), 3)
self.assertEqual(len(gpx.routes[1].points), 2)
# trk:
self.assertEqual(len(gpx.tracks), 2)
self.assertEqual(gpx.tracks[0].name, 'example name t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/name').firstChild.nodeValue, 'example name t')
self.assertEqual(gpx.tracks[0].comment, 'example cmt t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/cmt').firstChild.nodeValue, 'example cmt t')
self.assertEqual(gpx.tracks[0].description, 'example desc t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/desc').firstChild.nodeValue, 'example desc t')
self.assertEqual(gpx.tracks[0].source, 'example src t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/src').firstChild.nodeValue, 'example src t')
self.assertEqual(gpx.tracks[0].link, 'example url t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/url').firstChild.nodeValue, 'example url t')
self.assertEqual(gpx.tracks[0].link_text, 'example urlname t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/urlname').firstChild.nodeValue, 'example urlname t')
self.assertEqual(gpx.tracks[0].number, 1)
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/number').firstChild.nodeValue, '1')
# trkpt:
self.assertEqual(gpx.tracks[0].segments[0].points[0].elevation, 11.1)
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/ele').firstChild.nodeValue, '11.1')
self.assertEqual(gpx.tracks[0].segments[0].points[0].time, mod_datetime.datetime(2013, 1, 1, 12, 0, 4, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/time').firstChild.nodeValue in ('2013-01-01T12:00:04Z', '2013-01-01T12:00:04'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].magnetic_variation, 12)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/magvar').firstChild.nodeValue in ('12.0', '12'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].geoid_height, 13.0)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/geoidheight').firstChild.nodeValue in ('13.0', '13'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].name, 'example name t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/name').firstChild.nodeValue, 'example name t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].comment, 'example cmt t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/cmt').firstChild.nodeValue, 'example cmt t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].description, 'example desc t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/desc').firstChild.nodeValue, 'example desc t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].source, 'example src t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/src').firstChild.nodeValue, 'example src t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].link, 'example url t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/url').firstChild.nodeValue, 'example url t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].link_text, 'example urlname t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/urlname').firstChild.nodeValue, 'example urlname t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].symbol, 'example sym t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/sym').firstChild.nodeValue, 'example sym t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].type, 'example type t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/type').firstChild.nodeValue, 'example type t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].type_of_gpx_fix, '3d')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/fix').firstChild.nodeValue, '3d')
self.assertEqual(gpx.tracks[0].segments[0].points[0].satellites, 100)
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/sat').firstChild.nodeValue, '100')
self.assertEqual(gpx.tracks[0].segments[0].points[0].vertical_dilution, 102.)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/vdop').firstChild.nodeValue in ('102.0', '102'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].horizontal_dilution, 101)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/hdop').firstChild.nodeValue in ('101.0', '101'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].position_dilution, 103)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/pdop').firstChild.nodeValue in ('103.0', '103'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].age_of_dgps_data, 104)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/ageofdgpsdata').firstChild.nodeValue in ('104.0', '104'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].dgps_id, '99')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/dgpsid').firstChild.nodeValue, '99')
def test_gpx_11_fields(self):
""" Test (de) serialization all gpx1.0 fields """
with open('test_files/gpx1.1_with_all_fields.gpx') as f:
xml = f.read()
original_gpx = mod_gpxpy.parse(xml)
# Serialize and parse again to be sure that all is preserved:
reparsed_gpx = mod_gpxpy.parse(original_gpx.to_xml('1.1'))
original_dom = mod_minidom.parseString(xml)
reparsed_dom = mod_minidom.parseString(reparsed_gpx.to_xml('1.1'))
namespace = '{https://github.com/tkrajina/gpxpy}'
for gpx in (original_gpx, reparsed_gpx):
for dom in (original_dom, reparsed_dom):
self.assertEqual(gpx.version, '1.1')
self.assertEqual(get_dom_node(dom, 'gpx').attributes['version'].nodeValue, '1.1')
self.assertEqual(gpx.creator, '...')
self.assertEqual(get_dom_node(dom, 'gpx').attributes['creator'].nodeValue, '...')
self.assertEqual(gpx.name, 'example name')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/name').firstChild.nodeValue, 'example name')
self.assertEqual(gpx.description, 'example description')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/desc').firstChild.nodeValue, 'example description')
self.assertEqual(gpx.author_name, 'author name')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/author/name').firstChild.nodeValue, 'author name')
self.assertEqual(gpx.author_email, 'aaa@bbb.com')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/author/email').attributes['id'].nodeValue, 'aaa')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/author/email').attributes['domain'].nodeValue, 'bbb.com')
self.assertEqual(gpx.author_link, 'http://link')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/author/link').attributes['href'].nodeValue, 'http://link')
self.assertEqual(gpx.author_link_text, 'link text')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/author/link/text').firstChild.nodeValue, 'link text')
self.assertEqual(gpx.author_link_type, 'link type')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/author/link/type').firstChild.nodeValue, 'link type')
self.assertEqual(gpx.copyright_author, 'gpxauth')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/copyright').attributes['author'].nodeValue, 'gpxauth')
self.assertEqual(gpx.copyright_year, '2013')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/copyright/year').firstChild.nodeValue, '2013')
self.assertEqual(gpx.copyright_license, 'lic')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/copyright/license').firstChild.nodeValue, 'lic')
self.assertEqual(gpx.link, 'http://link2')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/link').attributes['href'].nodeValue, 'http://link2')
self.assertEqual(gpx.link_text, 'link text2')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/link/text').firstChild.nodeValue, 'link text2')
self.assertEqual(gpx.link_type, 'link type2')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/link/type').firstChild.nodeValue, 'link type2')
self.assertEqual(gpx.time, mod_datetime.datetime(2013, 1, 1, 12, 0, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertTrue(get_dom_node(dom, 'gpx/metadata/time').firstChild.nodeValue in ('2013-01-01T12:00:00Z', '2013-01-01T12:00:00'))
self.assertEqual(gpx.keywords, 'example keywords')
self.assertEqual(get_dom_node(dom, 'gpx/metadata/keywords').firstChild.nodeValue, 'example keywords')
self.assertEqual(gpx.bounds.min_latitude, 1.2)
self.assertEqual(get_dom_node(dom, 'gpx/metadata/bounds').attributes['minlat'].value, '1.2')
# TODO
self.assertEqual(len(gpx.metadata_extensions), 3)
aaa = mod_etree.Element(namespace+'aaa')
aaa.text = 'bbb'
aaa.tail = ''
self.assertTrue(elements_equal(gpx.metadata_extensions[0], aaa))
bbb = mod_etree.Element(namespace+'bbb')
bbb.text = 'ccc'
bbb.tail = ''
self.assertTrue(elements_equal(gpx.metadata_extensions[1], bbb))
ccc = mod_etree.Element(namespace+'ccc')
ccc.text = 'ddd'
ccc.tail = ''
self.assertTrue(elements_equal(gpx.metadata_extensions[2], ccc))
# get_dom_node function is not escaped and so fails on proper namespaces
#self.assertEqual(get_dom_node(dom, 'gpx/metadata/extensions/{}aaa'.format(namespace)).firstChild.nodeValue, 'bbb')
#self.assertEqual(get_dom_node(dom, 'gpx/metadata/extensions/bbb').firstChild.nodeValue, 'ccc')
#self.assertEqual(get_dom_node(dom, 'gpx/metadata/extensions/ccc').firstChild.nodeValue, 'ddd')
self.assertEqual(2, len(gpx.waypoints))
self.assertEqual(gpx.waypoints[0].latitude, 12.3)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]').attributes['lat'].value, '12.3')
self.assertEqual(gpx.waypoints[0].longitude, 45.6)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]').attributes['lon'].value, '45.6')
self.assertEqual(gpx.waypoints[0].longitude, 45.6)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]').attributes['lon'].value, '45.6')
self.assertEqual(gpx.waypoints[0].elevation, 75.1)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/ele').firstChild.nodeValue, '75.1')
self.assertEqual(gpx.waypoints[0].time, mod_datetime.datetime(2013, 1, 2, 2, 3, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/time').firstChild.nodeValue, '2013-01-02T02:03:00Z')
self.assertEqual(gpx.waypoints[0].magnetic_variation, 1.1)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/magvar').firstChild.nodeValue, '1.1')
self.assertEqual(gpx.waypoints[0].geoid_height, 2.0)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/geoidheight').firstChild.nodeValue, '2.0')
self.assertEqual(gpx.waypoints[0].name, 'example name')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/name').firstChild.nodeValue, 'example name')
self.assertEqual(gpx.waypoints[0].comment, 'example cmt')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/cmt').firstChild.nodeValue, 'example cmt')
self.assertEqual(gpx.waypoints[0].description, 'example desc')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/desc').firstChild.nodeValue, 'example desc')
self.assertEqual(gpx.waypoints[0].source, 'example src')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/src').firstChild.nodeValue, 'example src')
self.assertEqual(gpx.waypoints[0].link, 'http://link3')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/link').attributes['href'].nodeValue, 'http://link3')
self.assertEqual(gpx.waypoints[0].link_text, 'link text3')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/link/text').firstChild.nodeValue, 'link text3')
self.assertEqual(gpx.waypoints[0].link_type, 'link type3')
self.assertEqual(get_dom_node(dom, 'gpx/wpt[0]/link/type').firstChild.nodeValue, 'link type3')
self.assertEqual(gpx.waypoints[1].latitude, 13.4)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[1]').attributes['lat'].value, '13.4')
self.assertEqual(gpx.waypoints[1].longitude, 46.7)
self.assertEqual(get_dom_node(dom, 'gpx/wpt[1]').attributes['lon'].value, '46.7')
self.assertEqual(2, len(gpx.waypoints[0].extensions))
self.assertTrue(elements_equal(gpx.waypoints[0].extensions[0], aaa))
self.assertTrue(elements_equal(gpx.waypoints[0].extensions[1], ccc))
# 1. rte
self.assertEqual(gpx.routes[0].name, 'example name')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/name').firstChild.nodeValue, 'example name')
self.assertEqual(gpx.routes[0].comment, 'example cmt')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/cmt').firstChild.nodeValue, 'example cmt')
self.assertEqual(gpx.routes[0].description, 'example desc')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/desc').firstChild.nodeValue, 'example desc')
self.assertEqual(gpx.routes[0].source, 'example src')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/src').firstChild.nodeValue, 'example src')
self.assertEqual(gpx.routes[0].link, 'http://link3')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/link').attributes['href'].nodeValue, 'http://link3')
self.assertEqual(gpx.routes[0].link_text, 'link text3')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/link/text').firstChild.nodeValue, 'link text3')
self.assertEqual(gpx.routes[0].link_type, 'link type3')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/link/type').firstChild.nodeValue, 'link type3')
self.assertEqual(gpx.routes[0].number, 7)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/number').firstChild.nodeValue, '7')
self.assertEqual(gpx.routes[0].type, 'rte type')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/type').firstChild.nodeValue, 'rte type')
self.assertEqual(2, len(gpx.routes[0].extensions))
rtee1 = mod_etree.Element(namespace+'rtee1')
rtee1.text = '1'
rtee1.tail = ''
self.assertTrue(elements_equal(gpx.routes[0].extensions[0], rtee1))
rtee2 = mod_etree.Element(namespace+'rtee2')
rtee2.text = '2'
rtee2.tail = ''
self.assertTrue(elements_equal(gpx.routes[0].extensions[1], rtee2))
# 2. rte
self.assertEqual(gpx.routes[1].name, 'second route')
self.assertEqual(get_dom_node(dom, 'gpx/rte[1]/name').firstChild.nodeValue, 'second route')
self.assertEqual(gpx.routes[1].description, 'example desc 2')
self.assertEqual(get_dom_node(dom, 'gpx/rte[1]/desc').firstChild.nodeValue, 'example desc 2')
self.assertEqual(gpx.routes[1].link, None)
self.assertEqual(gpx.routes[0].number, 7)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/number').firstChild.nodeValue, '7')
self.assertEqual(len(gpx.routes[0].points), 3)
self.assertEqual(len(gpx.routes[1].points), 2)
# Rtept
self.assertEqual(gpx.routes[0].points[0].latitude, 10)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]').attributes['lat'].value in ('10.0', '10'))
self.assertEqual(gpx.routes[0].points[0].longitude, 20)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]').attributes['lon'].value in ('20.0', '20'))
self.assertEqual(gpx.routes[0].points[0].elevation, 75.1)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/ele').firstChild.nodeValue, '75.1')
self.assertEqual(gpx.routes[0].points[0].time, mod_datetime.datetime(2013, 1, 2, 2, 3, 3, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/time').firstChild.nodeValue, '2013-01-02T02:03:03Z')
self.assertEqual(gpx.routes[0].points[0].magnetic_variation, 1.2)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/magvar').firstChild.nodeValue, '1.2')
self.assertEqual(gpx.routes[0].points[0].geoid_height, 2.1)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/geoidheight').firstChild.nodeValue, '2.1')
self.assertEqual(gpx.routes[0].points[0].name, 'example name r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/name').firstChild.nodeValue, 'example name r')
self.assertEqual(gpx.routes[0].points[0].comment, 'example cmt r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/cmt').firstChild.nodeValue, 'example cmt r')
self.assertEqual(gpx.routes[0].points[0].description, 'example desc r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/desc').firstChild.nodeValue, 'example desc r')
self.assertEqual(gpx.routes[0].points[0].source, 'example src r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/src').firstChild.nodeValue, 'example src r')
self.assertEqual(gpx.routes[0].points[0].link, 'http://linkrtept')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/link').attributes['href'].nodeValue, 'http://linkrtept')
self.assertEqual(gpx.routes[0].points[0].link_text, 'rtept link')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/link/text').firstChild.nodeValue, 'rtept link')
self.assertEqual(gpx.routes[0].points[0].link_type, 'rtept link type')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/link/type').firstChild.nodeValue, 'rtept link type')
self.assertEqual(gpx.routes[0].points[0].symbol, 'example sym r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/sym').firstChild.nodeValue, 'example sym r')
self.assertEqual(gpx.routes[0].points[0].type, 'example type r')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/type').firstChild.nodeValue, 'example type r')
self.assertEqual(gpx.routes[0].points[0].type_of_gpx_fix, '3d')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/fix').firstChild.nodeValue, '3d')
self.assertEqual(gpx.routes[0].points[0].satellites, 6)
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/sat').firstChild.nodeValue, '6')
self.assertEqual(gpx.routes[0].points[0].vertical_dilution, 8)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/vdop').firstChild.nodeValue in ('8.0', '8'))
self.assertEqual(gpx.routes[0].points[0].horizontal_dilution, 7)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/hdop').firstChild.nodeValue in ('7.0', '7'))
self.assertEqual(gpx.routes[0].points[0].position_dilution, 9)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/pdop').firstChild.nodeValue in ('9.0', '9'))
self.assertEqual(gpx.routes[0].points[0].age_of_dgps_data, 10)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/ageofdgpsdata').firstChild.nodeValue in ('10.0', '10'))
self.assertEqual(gpx.routes[0].points[0].dgps_id, '99')
self.assertEqual(get_dom_node(dom, 'gpx/rte[0]/rtept[0]/dgpsid').firstChild.nodeValue, '99')
# second rtept:
self.assertEqual(gpx.routes[0].points[1].latitude, 11)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[1]').attributes['lat'].value in ('11.0', '11'))
self.assertEqual(gpx.routes[0].points[1].longitude, 21)
self.assertTrue(get_dom_node(dom, 'gpx/rte[0]/rtept[1]').attributes['lon'].value in ('21.0', '21'))
# gpx ext:
self.assertEqual(1, len(gpx.extensions))
gpxext = mod_etree.Element(namespace+'gpxext')
gpxext.text = '...'
gpxext.tail = ''
self.assertTrue(elements_equal(gpx.extensions[0], gpxext))
# trk
self.assertEqual(len(gpx.tracks), 2)
self.assertEqual(gpx.tracks[0].name, 'example name t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/name').firstChild.nodeValue, 'example name t')
self.assertEqual(gpx.tracks[0].comment, 'example cmt t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/cmt').firstChild.nodeValue, 'example cmt t')
self.assertEqual(gpx.tracks[0].description, 'example desc t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/desc').firstChild.nodeValue, 'example desc t')
self.assertEqual(gpx.tracks[0].source, 'example src t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/src').firstChild.nodeValue, 'example src t')
self.assertEqual(gpx.tracks[0].link, 'http://trk')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/link').attributes['href'].nodeValue, 'http://trk')
self.assertEqual(gpx.tracks[0].link_text, 'trk link')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/link/text').firstChild.nodeValue, 'trk link')
self.assertEqual(gpx.tracks[0].link_type, 'trk link type')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/link/type').firstChild.nodeValue, 'trk link type')
self.assertEqual(gpx.tracks[0].number, 1)
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/number').firstChild.nodeValue, '1')
self.assertEqual(gpx.tracks[0].type, 't')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/type').firstChild.nodeValue, 't')
self.assertEqual(1, len(gpx.tracks[0].extensions))
a1 = mod_etree.Element(namespace+'a1')
a1.text = '2'
a1.tail = ''
self.assertTrue(elements_equal(gpx.tracks[0].extensions[0], a1))
# trkpt:
self.assertEqual(gpx.tracks[0].segments[0].points[0].elevation, 11.1)
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/ele').firstChild.nodeValue, '11.1')
self.assertEqual(gpx.tracks[0].segments[0].points[0].time, mod_datetime.datetime(2013, 1, 1, 12, 0, 4, tzinfo=mod_gpxfield.SimpleTZ()))
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/time').firstChild.nodeValue in ('2013-01-01T12:00:04Z', '2013-01-01T12:00:04'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].magnetic_variation, 12)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/magvar').firstChild.nodeValue in ('12.0', '12'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].geoid_height, 13.0)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/geoidheight').firstChild.nodeValue in ('13.0', '13'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].name, 'example name t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/name').firstChild.nodeValue, 'example name t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].comment, 'example cmt t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/cmt').firstChild.nodeValue, 'example cmt t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].description, 'example desc t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/desc').firstChild.nodeValue, 'example desc t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].source, 'example src t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/src').firstChild.nodeValue, 'example src t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].link, 'http://trkpt')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/link').attributes['href'].nodeValue, 'http://trkpt')
self.assertEqual(gpx.tracks[0].segments[0].points[0].link_text, 'trkpt link')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/link/text').firstChild.nodeValue, 'trkpt link')
self.assertEqual(gpx.tracks[0].segments[0].points[0].link_type, 'trkpt link type')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/link/type').firstChild.nodeValue, 'trkpt link type')
self.assertEqual(gpx.tracks[0].segments[0].points[0].symbol, 'example sym t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/sym').firstChild.nodeValue, 'example sym t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].type, 'example type t')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/type').firstChild.nodeValue, 'example type t')
self.assertEqual(gpx.tracks[0].segments[0].points[0].type_of_gpx_fix, '3d')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/fix').firstChild.nodeValue, '3d')
self.assertEqual(gpx.tracks[0].segments[0].points[0].satellites, 100)
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/sat').firstChild.nodeValue, '100')
self.assertEqual(gpx.tracks[0].segments[0].points[0].vertical_dilution, 102.)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/vdop').firstChild.nodeValue in ('102.0', '102'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].horizontal_dilution, 101)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/hdop').firstChild.nodeValue in ('101.0', '101'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].position_dilution, 103)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/pdop').firstChild.nodeValue in ('103.0', '103'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].age_of_dgps_data, 104)
self.assertTrue(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/ageofdgpsdata').firstChild.nodeValue in ('104.0', '104'))
self.assertEqual(gpx.tracks[0].segments[0].points[0].dgps_id, '99')
self.assertEqual(get_dom_node(dom, 'gpx/trk[0]/trkseg[0]/trkpt[0]/dgpsid').firstChild.nodeValue, '99')
self.assertEqual(1, len(gpx.tracks[0].segments[0].points[0].extensions))
last = mod_etree.Element(namespace+'last')
last.text = 'true'
last.tail = ''
self.assertTrue(elements_equal(gpx.tracks[0].segments[0].points[0].extensions[0], last))
# Validated with SAXParser in "make test"
# Clear extensions because those should be declared in the but
# gpxpy don't have support for this (yet):
reparsed_gpx.extensions = {}
reparsed_gpx.metadata_extensions = {}
for waypoint in reparsed_gpx.waypoints:
waypoint.extensions = {}
for route in reparsed_gpx.routes:
route.extensions = {}
for point in route.points:
point.extensions = {}
for track in reparsed_gpx.tracks:
track.extensions = {}
for segment in track.segments:
segment.extensions = {}
for point in segment.points:
point.extensions = {}
with open('test_files/validation_gpx11.gpx', 'w') as f:
f.write(reparsed_gpx.to_xml())
def test_xml_chars_encode_decode(self):
gpx = mod_gpxpy.gpx.GPX()
gpx.name = "Testjkljkl"
print(gpx.to_xml())
gpx_2 = mod_gpxpy.parse(gpx.to_xml())
self.assertTrue('Test<a>jkljkl</gpx>' in gpx_2.to_xml())
def test_10_to_11_conversion(self):
"""
This test checks that reparsing from 1.0 to 1.1 and from 1.1 to 1.0
will preserve all fields common for both versions.
"""
original_gpx = mod_gpx.GPX()
original_gpx.creator = 'cr'
original_gpx.name = 'q'
original_gpx.description = 'w'
original_gpx.time = mod_datetime.datetime(2014, 4, 7, 21, 17, 39, tzinfo=mod_gpxfield.SimpleTZ())
original_gpx.bounds = mod_gpx.GPXBounds(1, 2, 3, 4)
original_gpx.author_name = '789'
original_gpx.author_email = '256@aaa'
original_gpx.link = 'http://9890'
original_gpx.link_text = '77888'
original_gpx.keywords = 'kw'
original_waypoint = mod_gpx.GPXWaypoint()
original_waypoint.latitude = 12.3
original_waypoint.longitude = 13.4
original_waypoint.elevation = 121.89
original_waypoint.time = mod_datetime.datetime(2015, 5, 8, 21, 17, 39, tzinfo=mod_gpxfield.SimpleTZ())
original_waypoint.magnetic_variation = 1
original_waypoint.geoid_height = 1
original_waypoint.name = 'n'
original_waypoint.comment = 'cm'
original_waypoint.description = 'des'
original_waypoint.source = 'src'
original_waypoint.symbol = 'sym'
original_waypoint.type = 'ty'
original_waypoint.type_of_gpx_fix = 'dgps'
original_waypoint.satellites = 13
original_waypoint.horizontal_dilution = 14
original_waypoint.vertical_dilution = 15
original_waypoint.position_dilution = 16
original_waypoint.age_of_dgps_data = 16
original_waypoint.dgps_id = '17'
original_gpx.waypoints.append(original_waypoint)
original_route = mod_gpx.GPXRoute()
original_route.name = 'rten'
original_route.comment = 'rtecm'
original_route.description = 'rtedesc'
original_route.source = 'rtesrc'
# TODO url
original_route.number = 101
original_route_points = mod_gpx.GPXRoutePoint()
original_route_points.latitude = 34.5
original_route_points.longitude = 56.6
original_route_points.elevation = 1001
original_route_points.time = mod_datetime.datetime(2015, 5, 8, 21, 17, 17, tzinfo=mod_gpxfield.SimpleTZ())
original_route_points.magnetic_variation = 12
original_route_points.geoid_height = 13
original_route_points.name = 'aaaaa'
original_route_points.comment = 'wwww'
original_route_points.description = 'cccc'
original_route_points.source = 'qqq'
# TODO url
original_route_points.symbol = 'a.png'
original_route_points.type = '2'
original_route_points.type_of_gpx_fix = 'pps'
original_route_points.satellites = 23
original_route_points.horizontal_dilution = 19
original_route_points.vertical_dilution = 20
original_route_points.position_dilution = 21
original_route_points.age_of_dgps_data = 22
original_route_points.dgps_id = '23'
original_route.points.append(original_route_points)
original_gpx.routes.append(original_route)
original_track = mod_gpx.GPXTrack()
original_track.name = 'rten'
original_track.comment = 'rtecm'
original_track.description = 'rtedesc'
original_track.source = 'rtesrc'
# TODO url
original_track.number = 101
original_track_point = mod_gpx.GPXTrackPoint()
original_track_point.latitude = 34.6
original_track_point.longitude = 57.6
original_track_point.elevation = 1002
original_track_point.time = mod_datetime.datetime(2016, 5, 8, 21, 17, 17, tzinfo=mod_gpxfield.SimpleTZ())
original_track_point.magnetic_variation = 13
original_track_point.geoid_height = 14
original_track_point.name = 'aaaaajkjk'
original_track_point.comment = 'wwwwii'
original_track_point.description = 'ciccc'
original_track_point.source = 'qssqq'
# TODO url
original_track_point.symbol = 'ai.png'
original_track_point.type = '3'
original_track_point.type_of_gpx_fix = 'pps'
original_track_point.satellites = 24
original_track_point.horizontal_dilution = 20
original_track_point.vertical_dilution = 21
original_track_point.position_dilution = 22
original_track_point.age_of_dgps_data = 23
original_track_point.dgps_id = '22'
original_track.segments.append(mod_gpx.GPXTrackSegment())
original_track.segments[0].points.append(original_track_point)
original_gpx.tracks.append(original_track)
# Convert do GPX1.0:
xml_10 = original_gpx.to_xml('1.0')
print(xml_10)
self.assertTrue('http://www.topografix.com/GPX/1/0' in xml_10)
#pretty_print_xml(xml_10)
gpx_1 = mod_gpxpy.parse(xml_10)
# Convert do GPX1.1:
xml_11 = gpx_1.to_xml('1.1')
print(xml_11)
self.assertTrue('http://www.topografix.com/GPX/1/1' in xml_11 and 'metadata' in xml_11)
#pretty_print_xml(xml_11)
gpx_2 = mod_gpxpy.parse(xml_11)
# Convert do GPX1.0 again:
xml_10 = gpx_2.to_xml('1.0')
self.assertTrue('http://www.topografix.com/GPX/1/0' in xml_10)
#pretty_print_xml(xml_10)
gpx_3 = mod_gpxpy.parse(xml_10)
for gpx in (gpx_1, gpx_2, gpx_3, ):
self.assertTrue(gpx.creator is not None)
self.assertEqual(original_gpx.creator, gpx.creator)
self.assertTrue(gpx.name is not None)
self.assertEqual(original_gpx.name, gpx.name)
self.assertTrue(gpx.description is not None)
self.assertEqual(original_gpx.description, gpx.description)
self.assertTrue(gpx.keywords is not None)
self.assertEqual(original_gpx.keywords, gpx.keywords)
self.assertTrue(gpx.time is not None)
self.assertEqual(original_gpx.time, gpx.time)
self.assertTrue(gpx.author_name is not None)
self.assertEqual(original_gpx.author_name, gpx.author_name)
self.assertTrue(gpx.author_email is not None)
self.assertEqual(original_gpx.author_email, gpx.author_email)
self.assertTrue(gpx.link is not None)
self.assertEqual(original_gpx.link, gpx.link)
self.assertTrue(gpx.link_text is not None)
self.assertEqual(original_gpx.link_text, gpx.link_text)
self.assertTrue(gpx.bounds is not None)
self.assertEqual(tuple(original_gpx.bounds), tuple(gpx.bounds))
self.assertEqual(1, len(gpx.waypoints))
self.assertTrue(gpx.waypoints[0].latitude is not None)
self.assertEqual(original_gpx.waypoints[0].latitude, gpx.waypoints[0].latitude)
self.assertTrue(gpx.waypoints[0].longitude is not None)
self.assertEqual(original_gpx.waypoints[0].longitude, gpx.waypoints[0].longitude)
self.assertTrue(gpx.waypoints[0].elevation is not None)
self.assertEqual(original_gpx.waypoints[0].elevation, gpx.waypoints[0].elevation)
self.assertTrue(gpx.waypoints[0].time is not None)
self.assertEqual(original_gpx.waypoints[0].time, gpx.waypoints[0].time)
self.assertTrue(gpx.waypoints[0].magnetic_variation is not None)
self.assertEqual(original_gpx.waypoints[0].magnetic_variation, gpx.waypoints[0].magnetic_variation)
self.assertTrue(gpx.waypoints[0].geoid_height is not None)
self.assertEqual(original_gpx.waypoints[0].geoid_height, gpx.waypoints[0].geoid_height)
self.assertTrue(gpx.waypoints[0].name is not None)
self.assertEqual(original_gpx.waypoints[0].name, gpx.waypoints[0].name)
self.assertTrue(gpx.waypoints[0].comment is not None)
self.assertEqual(original_gpx.waypoints[0].comment, gpx.waypoints[0].comment)
self.assertTrue(gpx.waypoints[0].description is not None)
self.assertEqual(original_gpx.waypoints[0].description, gpx.waypoints[0].description)
self.assertTrue(gpx.waypoints[0].source is not None)
self.assertEqual(original_gpx.waypoints[0].source, gpx.waypoints[0].source)
# TODO: Link/url
self.assertTrue(gpx.waypoints[0].symbol is not None)
self.assertEqual(original_gpx.waypoints[0].symbol, gpx.waypoints[0].symbol)
self.assertTrue(gpx.waypoints[0].type is not None)
self.assertEqual(original_gpx.waypoints[0].type, gpx.waypoints[0].type)
self.assertTrue(gpx.waypoints[0].type_of_gpx_fix is not None)
self.assertEqual(original_gpx.waypoints[0].type_of_gpx_fix, gpx.waypoints[0].type_of_gpx_fix)
self.assertTrue(gpx.waypoints[0].satellites is not None)
self.assertEqual(original_gpx.waypoints[0].satellites, gpx.waypoints[0].satellites)
self.assertTrue(gpx.waypoints[0].horizontal_dilution is not None)
self.assertEqual(original_gpx.waypoints[0].horizontal_dilution, gpx.waypoints[0].horizontal_dilution)
self.assertTrue(gpx.waypoints[0].vertical_dilution is not None)
self.assertEqual(original_gpx.waypoints[0].vertical_dilution, gpx.waypoints[0].vertical_dilution)
self.assertTrue(gpx.waypoints[0].position_dilution is not None)
self.assertEqual(original_gpx.waypoints[0].position_dilution, gpx.waypoints[0].position_dilution)
self.assertTrue(gpx.waypoints[0].age_of_dgps_data is not None)
self.assertEqual(original_gpx.waypoints[0].age_of_dgps_data, gpx.waypoints[0].age_of_dgps_data)
self.assertTrue(gpx.waypoints[0].dgps_id is not None)
self.assertEqual(original_gpx.waypoints[0].dgps_id, gpx.waypoints[0].dgps_id)
# route(s):
self.assertTrue(gpx.routes[0].name is not None)
self.assertEqual(original_gpx.routes[0].name, gpx.routes[0].name)
self.assertTrue(gpx.routes[0].comment is not None)
self.assertEqual(original_gpx.routes[0].comment, gpx.routes[0].comment)
self.assertTrue(gpx.routes[0].description is not None)
self.assertEqual(original_gpx.routes[0].description, gpx.routes[0].description)
self.assertTrue(gpx.routes[0].source is not None)
self.assertEqual(original_gpx.routes[0].source, gpx.routes[0].source)
self.assertTrue(gpx.routes[0].number is not None)
self.assertEqual(original_gpx.routes[0].number, gpx.routes[0].number)
self.assertTrue(gpx.routes[0].points[0].latitude is not None)
self.assertEqual(original_gpx.routes[0].points[0].latitude, gpx.routes[0].points[0].latitude)
self.assertTrue(gpx.routes[0].points[0].longitude is not None)
self.assertEqual(original_gpx.routes[0].points[0].longitude, gpx.routes[0].points[0].longitude)
self.assertTrue(gpx.routes[0].points[0].elevation is not None)
self.assertEqual(original_gpx.routes[0].points[0].elevation, gpx.routes[0].points[0].elevation)
self.assertTrue(gpx.routes[0].points[0].time is not None)
self.assertEqual(original_gpx.routes[0].points[0].time, gpx.routes[0].points[0].time)
self.assertTrue(gpx.routes[0].points[0].magnetic_variation is not None)
self.assertEqual(original_gpx.routes[0].points[0].magnetic_variation, gpx.routes[0].points[0].magnetic_variation)
self.assertTrue(gpx.routes[0].points[0].geoid_height is not None)
self.assertEqual(original_gpx.routes[0].points[0].geoid_height, gpx.routes[0].points[0].geoid_height)
self.assertTrue(gpx.routes[0].points[0].name is not None)
self.assertEqual(original_gpx.routes[0].points[0].name, gpx.routes[0].points[0].name)
self.assertTrue(gpx.routes[0].points[0].comment is not None)
self.assertEqual(original_gpx.routes[0].points[0].comment, gpx.routes[0].points[0].comment)
self.assertTrue(gpx.routes[0].points[0].description is not None)
self.assertEqual(original_gpx.routes[0].points[0].description, gpx.routes[0].points[0].description)
self.assertTrue(gpx.routes[0].points[0].source is not None)
self.assertEqual(original_gpx.routes[0].points[0].source, gpx.routes[0].points[0].source)
self.assertTrue(gpx.routes[0].points[0].symbol is not None)
self.assertEqual(original_gpx.routes[0].points[0].symbol, gpx.routes[0].points[0].symbol)
self.assertTrue(gpx.routes[0].points[0].type is not None)
self.assertEqual(original_gpx.routes[0].points[0].type, gpx.routes[0].points[0].type)
self.assertTrue(gpx.routes[0].points[0].type_of_gpx_fix is not None)
self.assertEqual(original_gpx.routes[0].points[0].type_of_gpx_fix, gpx.routes[0].points[0].type_of_gpx_fix)
self.assertTrue(gpx.routes[0].points[0].satellites is not None)
self.assertEqual(original_gpx.routes[0].points[0].satellites, gpx.routes[0].points[0].satellites)
self.assertTrue(gpx.routes[0].points[0].horizontal_dilution is not None)
self.assertEqual(original_gpx.routes[0].points[0].horizontal_dilution, gpx.routes[0].points[0].horizontal_dilution)
self.assertTrue(gpx.routes[0].points[0].vertical_dilution is not None)
self.assertEqual(original_gpx.routes[0].points[0].vertical_dilution, gpx.routes[0].points[0].vertical_dilution)
self.assertTrue(gpx.routes[0].points[0].position_dilution is not None)
self.assertEqual(original_gpx.routes[0].points[0].position_dilution, gpx.routes[0].points[0].position_dilution)
self.assertTrue(gpx.routes[0].points[0].age_of_dgps_data is not None)
self.assertEqual(original_gpx.routes[0].points[0].age_of_dgps_data, gpx.routes[0].points[0].age_of_dgps_data)
self.assertTrue(gpx.routes[0].points[0].dgps_id is not None)
self.assertEqual(original_gpx.routes[0].points[0].dgps_id, gpx.routes[0].points[0].dgps_id)
# track(s):
self.assertTrue(gpx.tracks[0].name is not None)
self.assertEqual(original_gpx.tracks[0].name, gpx.tracks[0].name)
self.assertTrue(gpx.tracks[0].comment is not None)
self.assertEqual(original_gpx.tracks[0].comment, gpx.tracks[0].comment)
self.assertTrue(gpx.tracks[0].description is not None)
self.assertEqual(original_gpx.tracks[0].description, gpx.tracks[0].description)
self.assertTrue(gpx.tracks[0].source is not None)
self.assertEqual(original_gpx.tracks[0].source, gpx.tracks[0].source)
self.assertTrue(gpx.tracks[0].number is not None)
self.assertEqual(original_gpx.tracks[0].number, gpx.tracks[0].number)
self.assertTrue(gpx.tracks[0].segments[0].points[0].latitude is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].latitude, gpx.tracks[0].segments[0].points[0].latitude)
self.assertTrue(gpx.tracks[0].segments[0].points[0].longitude is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].longitude, gpx.tracks[0].segments[0].points[0].longitude)
self.assertTrue(gpx.tracks[0].segments[0].points[0].elevation is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].elevation, gpx.tracks[0].segments[0].points[0].elevation)
self.assertTrue(gpx.tracks[0].segments[0].points[0].time is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].time, gpx.tracks[0].segments[0].points[0].time)
self.assertTrue(gpx.tracks[0].segments[0].points[0].magnetic_variation is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].magnetic_variation, gpx.tracks[0].segments[0].points[0].magnetic_variation)
self.assertTrue(gpx.tracks[0].segments[0].points[0].geoid_height is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].geoid_height, gpx.tracks[0].segments[0].points[0].geoid_height)
self.assertTrue(gpx.tracks[0].segments[0].points[0].name is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].name, gpx.tracks[0].segments[0].points[0].name)
self.assertTrue(gpx.tracks[0].segments[0].points[0].comment is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].comment, gpx.tracks[0].segments[0].points[0].comment)
self.assertTrue(gpx.tracks[0].segments[0].points[0].description is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].description, gpx.tracks[0].segments[0].points[0].description)
self.assertTrue(gpx.tracks[0].segments[0].points[0].source is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].source, gpx.tracks[0].segments[0].points[0].source)
self.assertTrue(gpx.tracks[0].segments[0].points[0].symbol is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].symbol, gpx.tracks[0].segments[0].points[0].symbol)
self.assertTrue(gpx.tracks[0].segments[0].points[0].type is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].type, gpx.tracks[0].segments[0].points[0].type)
self.assertTrue(gpx.tracks[0].segments[0].points[0].type_of_gpx_fix is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].type_of_gpx_fix, gpx.tracks[0].segments[0].points[0].type_of_gpx_fix)
self.assertTrue(gpx.tracks[0].segments[0].points[0].satellites is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].satellites, gpx.tracks[0].segments[0].points[0].satellites)
self.assertTrue(gpx.tracks[0].segments[0].points[0].horizontal_dilution is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].horizontal_dilution, gpx.tracks[0].segments[0].points[0].horizontal_dilution)
self.assertTrue(gpx.tracks[0].segments[0].points[0].vertical_dilution is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].vertical_dilution, gpx.tracks[0].segments[0].points[0].vertical_dilution)
self.assertTrue(gpx.tracks[0].segments[0].points[0].position_dilution is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].position_dilution, gpx.tracks[0].segments[0].points[0].position_dilution)
self.assertTrue(gpx.tracks[0].segments[0].points[0].age_of_dgps_data is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].age_of_dgps_data, gpx.tracks[0].segments[0].points[0].age_of_dgps_data)
self.assertTrue(gpx.tracks[0].segments[0].points[0].dgps_id is not None)
self.assertEqual(original_gpx.tracks[0].segments[0].points[0].dgps_id, gpx.tracks[0].segments[0].points[0].dgps_id)
def test_min_max(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
gpx.tracks.append(track)
segment = mod_gpx.GPXTrackSegment()
track.segments.append(segment)
segment.points.append(mod_gpx.GPXTrackPoint(12, 13, elevation=100))
segment.points.append(mod_gpx.GPXTrackPoint(12, 13, elevation=200))
# Check for segment:
elevation_min, elevation_max = segment.get_elevation_extremes()
self.assertEqual(100, elevation_min)
self.assertEqual(200, elevation_max)
# Check for track:
elevation_min, elevation_max = track.get_elevation_extremes()
self.assertEqual(100, elevation_min)
self.assertEqual(200, elevation_max)
# Check for gpx:
elevation_min, elevation_max = gpx.get_elevation_extremes()
self.assertEqual(100, elevation_min)
self.assertEqual(200, elevation_max)
def test_distance_between_points_near_0_longitude(self):
""" Make sure that the distance function works properly when points have longitudes on opposite sides of the 0-longitude meridian """
distance = mod_geo.distance(latitude_1=0, longitude_1=0.1, elevation_1=0, latitude_2=0, longitude_2=-0.1, elevation_2=0, haversine=True)
print(distance)
self.assertTrue(distance < 230000)
distance = mod_geo.distance(latitude_1=0, longitude_1=0.1, elevation_1=0, latitude_2=0, longitude_2=-0.1, elevation_2=0, haversine=False)
print(distance)
self.assertTrue(distance < 230000)
distance = mod_geo.distance(latitude_1=0, longitude_1=0.1, elevation_1=0, latitude_2=0, longitude_2=360-0.1, elevation_2=0, haversine=True)
print(distance)
self.assertTrue(distance < 230000)
distance = mod_geo.distance(latitude_1=0, longitude_1=0.1, elevation_1=0, latitude_2=0, longitude_2=360-0.1, elevation_2=0, haversine=False)
print(distance)
self.assertTrue(distance < 230000)
def test_zero_latlng(self):
gpx = mod_gpx.GPX()
track = mod_gpx.GPXTrack()
gpx.tracks.append(track)
segment = mod_gpx.GPXTrackSegment()
track.segments.append(segment)
segment.points.append(mod_gpx.GPXTrackPoint(0, 0, elevation=0))
xml = gpx.to_xml()
print(xml)
self.assertEqual(1, len(gpx.tracks))
self.assertEqual(1, len(gpx.tracks[0].segments))
self.assertEqual(1, len(gpx.tracks[0].segments[0].points))
self.assertEqual(0, gpx.tracks[0].segments[0].points[0].latitude)
self.assertEqual(0, gpx.tracks[0].segments[0].points[0].longitude)
self.assertEqual(0, gpx.tracks[0].segments[0].points[0].elevation)
gpx2 = mod_gpxpy.parse(xml)
self.assertEqual(1, len(gpx2.tracks))
self.assertEqual(1, len(gpx2.tracks[0].segments))
self.assertEqual(1, len(gpx2.tracks[0].segments[0].points))
self.assertEqual(0, gpx2.tracks[0].segments[0].points[0].latitude)
self.assertEqual(0, gpx2.tracks[0].segments[0].points[0].longitude)
self.assertEqual(0, gpx2.tracks[0].segments[0].points[0].elevation)
def test_timezone_from_timestamp(self):
xml = '\n'
xml += '\n'
xml += '\n'
xml += '\n'
xml += '\n'
xml += '\n'
gpx = mod_gpxpy.parse(xml)
self.assertEqual(gpx.tracks[0].segments[0].points[0].time, mod_datetime.datetime(2014, 2, 2, 10, 23, 18, tzinfo=mod_gpxfield.SimpleTZ('01')))
def test_timestamp_with_single_digits(self):
xml = '\n'
xml += '\n'
xml += '\n'
xml += '\n'
xml += '\n'
xml += '\n'
gpx = mod_gpxpy.parse(xml)
self.assertEqual(gpx.tracks[0].segments[0].points[0].time, mod_datetime.datetime(2014, 2, 2, 2, 23, 18, tzinfo=mod_gpxfield.SimpleTZ('-02')))
def test_read_extensions(self):
""" Test extensions """
with open('test_files/gpx1.1_with_extensions.gpx') as f:
xml = f.read()
namespace = '{gpx.py}'
root1 = mod_etree.Element(namespace + 'aaa')
root1.text = 'bbb'
root1.tail = 'hhh'
root1.attrib[namespace+'jjj'] = 'kkk'
root2 = mod_etree.Element(namespace + 'ccc')
root2.text = ''
root2.tail = ''
subnode1 = mod_etree.SubElement(root2, namespace + 'ddd')
subnode1.text = 'eee'
subnode1.tail = ''
subnode1.attrib[namespace+'lll'] = 'mmm'
subnode1.attrib[namespace+'nnn'] = 'ooo'
subnode2 = mod_etree.SubElement(subnode1, namespace + 'fff')
subnode2.text = 'ggg'
subnode2.tail = 'iii'
gpx = mod_gpxpy.parse(xml)
print("Extension 1")
print(print_etree(gpx.waypoints[0].extensions[0]))
print()
self.assertTrue(elements_equal(gpx.waypoints[0].extensions[0], root1))
print("Extension 2")
print(print_etree(gpx.waypoints[0].extensions[1]))
print()
self.assertTrue(elements_equal(gpx.waypoints[0].extensions[1], root2))
def test_write_read_extensions(self):
namespace = '{gpx.py}'
nsmap = {'ext' : namespace[1:-1]}
root = mod_etree.Element(namespace + 'ccc')
root.text = ''
root.tail = ''
subnode1 = mod_etree.SubElement(root, namespace + 'ddd')
subnode1.text = 'eee'
subnode1.tail = ''
subnode1.attrib[namespace+'lll'] = 'mmm'
subnode1.attrib[namespace+'nnn'] = 'ooo'
subnode2 = mod_etree.SubElement(subnode1, namespace + 'fff')
subnode2.text = 'ggg'
subnode2.tail = 'iii'
subnode3 = mod_etree.SubElement(root, namespace + 'aaa')
subnode3.text = 'bbb'
gpx = mod_gpx.GPX()
gpx.nsmap = nsmap
print("Inserting Waypoint Extension")
gpx.waypoints.append(mod_gpx.GPXWaypoint())
gpx.waypoints[0].latitude = 5
gpx.waypoints[0].longitude = 10
gpx.waypoints[0].extensions.append(root)
print("Inserting Metadata Extension")
gpx.metadata_extensions.append(root)
print("Inserting GPX Extension")
gpx.extensions.append(root)
print("Inserting Route Extension")
gpx.routes.append(mod_gpx.GPXRoute())
gpx.routes[0].extensions.append(root)
print("Inserting Track Extension")
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].extensions.append(root)
print("Inserting Track Segment Extension")
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].extensions.append(root)
print("Inserting Track Point Extension")
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13))
gpx.tracks[0].segments[0].points[0].extensions.append(root)
xml = gpx.to_xml('1.1')
parsedgpx = mod_gpxpy.parse(xml)
print("Reading Waypoint Extension")
print(print_etree(gpx.waypoints[0].extensions[0]))
print()
self.assertTrue(elements_equal(gpx.waypoints[0].extensions[0], root))
print("Reading Metadata Extension")
self.assertTrue(elements_equal(gpx.metadata_extensions[0], root))
print("Reading GPX Extension")
self.assertTrue(elements_equal(gpx.extensions[0], root))
print("Reading Route Extension")
self.assertTrue(elements_equal(gpx.routes[0].extensions[0], root))
print("Reading Track Extension")
self.assertTrue(elements_equal(gpx.tracks[0].extensions[0], root))
print("Reading Track Segment Extension")
self.assertTrue(elements_equal(gpx.tracks[0].segments[0].extensions[0], root))
print("Reading Track Point Extension")
self.assertTrue(elements_equal(gpx.tracks[0].segments[0].points[0].extensions[0], root))
def test_no_10_extensions(self):
namespace = '{gpx.py}'
nsmap = {'ext' : namespace[1:-1]}
root = mod_etree.Element(namespace + 'tag')
root.text = 'text'
root.tail = 'tail'
gpx = mod_gpx.GPX()
gpx.nsmap = nsmap
print("Inserting Waypoint Extension")
gpx.waypoints.append(mod_gpx.GPXWaypoint())
gpx.waypoints[0].latitude = 5
gpx.waypoints[0].longitude = 10
gpx.waypoints[0].extensions.append(root)
print("Inserting Metadata Extension")
gpx.metadata_extensions.append(root)
print("Inserting GPX Extension")
gpx.extensions.append(root)
print("Inserting Route Extension")
gpx.routes.append(mod_gpx.GPXRoute())
gpx.routes[0].extensions.append(root)
print("Inserting Track Extension")
gpx.tracks.append(mod_gpx.GPXTrack())
gpx.tracks[0].extensions.append(root)
print("Inserting Track Segment Extension")
gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment())
gpx.tracks[0].segments[0].extensions.append(root)
print("Inserting Track Point Extension")
gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13))
gpx.tracks[0].segments[0].points[0].extensions.append(root)
xml = gpx.to_xml('1.0')
self.assertFalse('extension' in xml)
def test_extension_without_namespaces(self):
f = open('test_files/gpx1.1_with_extensions_without_namespaces.gpx', 'r')
gpx = mod_gpxpy.parse(f)
self.assertEqual(2, len(gpx.waypoints[0].extensions))
self.assertEqual("bbb", gpx.waypoints[0].extensions[0].text)
self.assertEqual("eee", gpx.waypoints[0].extensions[1].getchildren()[0].text.strip())
def test_with_ns_namespace(self):
gpx_with_ns = mod_gpxpy.parse("""
Foo Bar
running
23.6000003814697265625
125
75
""")
reparsed = mod_gpxpy.parse(gpx_with_ns.to_xml("1.1"))
for gpx in [gpx_with_ns, reparsed]:
extensions = gpx.tracks[0].segments[0].points[0].extensions
self.assertEqual(1, len(extensions))
self.assertEqual("125", extensions[0].getchildren()[0].text.strip())
self.assertEqual("75", extensions[0].getchildren()[1].text.strip())
def test_join_gpx_xml_files(self):
import gpxpy.gpxxml
files = [
'test_files/cerknicko-jezero.gpx',
'test_files/first_and_last_elevation.gpx',
'test_files/korita-zbevnica.gpx',
'test_files/Mojstrovka.gpx',
]
rtes = 0
wpts = 0
trcks = 0
points = 0
xmls = []
for file_name in files:
with open(file_name) as f:
contents = f.read()
gpx = mod_gpxpy.parse(contents)
wpts += len(gpx.waypoints)
rtes += len(gpx.routes)
trcks += len(gpx.tracks)
points += gpx.get_points_no()
xmls.append(contents)
result_xml = gpxpy.gpxxml.join_gpxs(xmls)
result_gpx = mod_gpxpy.parse(result_xml)
self.assertEqual(rtes, len(result_gpx.routes))
self.assertEqual(wpts, len(result_gpx.waypoints))
self.assertEqual(trcks, len(result_gpx.tracks))
self.assertEqual(points, result_gpx.get_points_no())
def test_small_floats(self):
"""GPX 1/1 does not allow scientific notation but that is what gpxpy writes right now."""
f = open('test_files/track-with-small-floats.gpx', 'r')
gpx = mod_gpxpy.parse(f)
xml = gpx.to_xml()
self.assertNotIn('e-', xml)
def test_gpx_fill_time_data_with_start_time_and_end_time(self):
gpx = self.parse('cerknicko-jezero.gpx')
start_time = mod_datetime.datetime(2018, 7, 4, 0, 0, 0)
end_time = mod_datetime.datetime(2018, 7, 4, 1, 0, 0)
gpx.fill_time_data_with_regular_intervals(start_time=start_time, end_time=end_time)
time_bounds = gpx.get_time_bounds()
tolerance = 1.0
start_time_diff = total_seconds(time_bounds.start_time - start_time)
end_time_diff = total_seconds(time_bounds.end_time - end_time)
self.assertLessEqual(mod_math.fabs(start_time_diff), tolerance)
self.assertLessEqual(mod_math.fabs(end_time_diff), tolerance)
def test_gpx_fill_time_data_with_start_time_and_end_time_and_time_delta(self):
gpx = self.parse('cerknicko-jezero.gpx')
start_time = mod_datetime.datetime(2018, 7, 4, 0, 0, 0)
time_delta = mod_datetime.timedelta(seconds=60)
end_time = mod_datetime.datetime(2018, 7, 4, 1, 0, 0)
gpx.fill_time_data_with_regular_intervals(start_time=start_time, time_delta=time_delta, end_time=end_time)
time_bounds = gpx.get_time_bounds()
tolerance = 1.0
start_time_diff = total_seconds(time_bounds.start_time - start_time)
end_time_diff = total_seconds(time_bounds.end_time - end_time)
self.assertLessEqual(mod_math.fabs(start_time_diff), tolerance)
self.assertLessEqual(mod_math.fabs(end_time_diff), tolerance)
def test_gpx_fill_time_data_with_start_time_and_time_delta(self):
gpx = self.parse('cerknicko-jezero.gpx')
start_time = mod_datetime.datetime(2018, 7, 4, 0, 0, 0)
time_delta = mod_datetime.timedelta(seconds=1)
end_time = start_time + (gpx.get_points_no() - 1) * time_delta
gpx.fill_time_data_with_regular_intervals(start_time=start_time, time_delta=time_delta)
time_bounds = gpx.get_time_bounds()
tolerance = 1.0
start_time_diff = total_seconds(time_bounds.start_time - start_time)
end_time_diff = total_seconds(time_bounds.end_time - end_time)
self.assertLessEqual(mod_math.fabs(start_time_diff), tolerance)
self.assertLessEqual(mod_math.fabs(end_time_diff), tolerance)
def test_gpx_fill_time_data_with_end_time_and_time_delta(self):
gpx = self.parse('cerknicko-jezero.gpx')
end_time = mod_datetime.datetime(2018, 7, 4, 0, 0, 0)
time_delta = mod_datetime.timedelta(seconds=1)
start_time = end_time - (gpx.get_points_no() - 1) * time_delta
gpx.fill_time_data_with_regular_intervals(time_delta=time_delta, end_time=end_time)
time_bounds = gpx.get_time_bounds()
tolerance = 1.0
start_time_diff = total_seconds(time_bounds.start_time - start_time)
end_time_diff = total_seconds(time_bounds.end_time - end_time)
self.assertLessEqual(mod_math.fabs(start_time_diff), tolerance)
self.assertLessEqual(mod_math.fabs(end_time_diff), tolerance)
def test_gpx_fill_time_data_raises_when_not_enough_parameters(self):
gpx = self.parse('cerknicko-jezero.gpx')
start_time = mod_datetime.datetime(2018, 7, 4, 0, 0, 0)
with self.assertRaises(mod_gpx.GPXException):
gpx.fill_time_data_with_regular_intervals(start_time=start_time)
def test_gpx_fill_time_data_raises_when_start_time_after_end_time(self):
gpx = self.parse('cerknicko-jezero.gpx')
start_time = mod_datetime.datetime(2018, 7, 4, 0, 0, 0)
end_time = mod_datetime.datetime(2018, 7, 3, 0, 0, 0)
with self.assertRaises(mod_gpx.GPXException):
gpx.fill_time_data_with_regular_intervals(start_time=start_time, end_time=end_time)
def test_gpx_fill_time_data_raises_when_force_is_false(self):
gpx = self.parse('Mojstrovka.gpx')
start_time = mod_datetime.datetime(2018, 7, 4, 0, 0, 0)
end_time = mod_datetime.datetime(2018, 7, 4, 1, 0, 0)
gpx.fill_time_data_with_regular_intervals(start_time=start_time, end_time=end_time)
with self.assertRaises(mod_gpx.GPXException):
gpx.fill_time_data_with_regular_intervals(start_time=start_time, end_time=end_time, force=False)
def test_single_quotes_xmlns(self):
gpx = mod_gpxpy.parse("""
100
""")
self.assertEqual(1, len(gpx.tracks))
self.assertEqual(1, len(gpx.tracks[0].segments))
self.assertEqual(1, len(gpx.tracks[0].segments[0].points))
def test_default_schema_locations(self):
gpx = mod_gpx.GPX()
with custom_open('test_files/default_schema_locations.gpx') as f:
self.assertEqual(gpx.to_xml(), f.read())
def test_custom_schema_locations(self):
gpx = mod_gpx.GPX()
gpx.nsmap = {
'gpxx': 'http://www.garmin.com/xmlschemas/GpxExtensions/v3',
}
gpx.schema_locations = [
'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',
]
with custom_open('test_files/custom_schema_locations.gpx') as f:
self.assertEqual(gpx.to_xml(), f.read())
def test_parse_custom_schema_locations(self):
gpx = self.parse('custom_schema_locations.gpx')
self.assertEqual(
[
'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',
],
gpx.schema_locations
)
def test_no_track(self):
xml = """
"""
gpx = mod_gpxpy.parse(xml)
self.assertEqual(0, len(gpx.tracks))
gpx2 = self.reparse(gpx)
self.assertEqual(0, len(gpx2.tracks))
def test_microsecond(self):
xml = ' '
gpx = mod_gpxpy.parse(xml)
gpx2 = self.reparse(gpx)
print(gpx2.to_xml())
self.assertEquals(207343, gpx2.tracks[0].segments[0].points[0].time.microsecond)
self.assertTrue("