Private
Public Access
1
0
This commit is contained in:
2025-10-23 10:27:13 +02:00
parent fd2e815414
commit d96e8f3b3c
6 changed files with 968 additions and 59 deletions

View File

@@ -58,7 +58,7 @@ from uuid import uuid4
def getrower(user):
try:
if user is None or user.is_anonymous:
if user is None or user.is_anonymous: # pragma: no cover
return None
except AttributeError: # pragma: no cover
if User.objects.get(id=user).is_anonymous:
@@ -77,12 +77,12 @@ def generate_job_id():
def valid_uploadoptions(uploadoptions):
fstr = uploadoptions.get('file', None)
if fstr is None:
if fstr is None: # pragma: no cover
return False, "Missing file in upload options."
# check if file can be found
if isinstance(fstr, str):
if not os.path.isfile(fstr):
if not os.path.isfile(fstr): # pragma: no cover
return False, f"File not found: {fstr}"
@@ -108,19 +108,19 @@ def is_invalid_file(file_path):
return False, "Image files are not supported for upload."
if fileformat == "json":
return False, "JSON files are not supported for upload."
if fileformat == "c2log":
if fileformat == "c2log": # pragma: no cover
return False, "Concept2 log files are not supported for upload."
if fileformat == "nostrokes":
if fileformat == "nostrokes": # pragma: no cover
return False, "No stroke data found in the file."
if fileformat == "kml":
return False, "KML files are not supported for upload."
if fileformat == "notgzip":
if fileformat == "notgzip": # pragma: no cover
return False, "The gzip file appears to be corrupted."
if fileformat == "rowprolog":
if fileformat == "rowprolog": # pragma: no cover
return False, "RowPro logbook summary files are not supported for upload."
if fileformat == "gpx":
return False, "GPX files are not supported for upload."
if fileformat == "unknown":
if fileformat == "unknown": # pragma: no cover
extension = os.path.splitext(f2)[1]
filename = os.path.splitext(f2)[0]
if extension == '.gz':
@@ -139,14 +139,14 @@ def is_invalid_file(file_path):
def upload_handler(uploadoptions, filename):
valid, message = valid_uploadoptions(uploadoptions)
if not valid:
if not valid: # pragma: no cover
return {
"status": "error",
"job_id": None,
"message": message
}
is_valid, message = is_invalid_file(filename)
if not is_valid:
if not is_valid: # pragma: no cover
os.remove(filename)
return {
"status": "error",
@@ -203,7 +203,7 @@ def unzip_and_process(zip_filepath, uploadoptions, parent_job_id, debug=False, *
def get_rower_from_uploadoptions(uploadoptions):
rowerform = TeamInviteForm(uploadoptions)
if not rowerform.is_valid():
if not rowerform.is_valid(): # pragma: no cover
return None
try:
u = rowerform.cleaned_data['user']
@@ -214,7 +214,7 @@ def get_rower_from_uploadoptions(uploadoptions):
if len(us):
u = us[0]
r = getrower(u)
else:
else: # pragma: no cover
r = None
for rwr in Rower.objects.all():
if rwr.emailalternatives is not None:
@@ -322,7 +322,7 @@ def update_workout_attributes(w, row, file_path, uploadoptions,
empowerside = 'starboard'
stravaid = uploadoptions.get('stravaid',0)
if stravaid != 0:
if stravaid != 0: # pragma: no cover
workoutsource = 'strava'
w.uploadedtostrava = stravaid
@@ -347,10 +347,10 @@ def update_workout_attributes(w, row, file_path, uploadoptions,
totaltime = row.df['TimeStamp (sec)'].max() - row.df['TimeStamp (sec)'].min()
try:
totaltime = totaltime + row.df.loc[:, ' ElapsedTime (sec)'].iloc[0]
except KeyError:
except KeyError: # pragma: no cover
pass
if np.isnan(totaltime):
if np.isnan(totaltime): # pragma: no cover
totaltime = 0
if uploadoptions.get('summary', '') == '':
@@ -358,11 +358,11 @@ def update_workout_attributes(w, row, file_path, uploadoptions,
else:
summary = uploadoptions.get('summary', '')
if uploadoptions.get('makeprivate', False):
if uploadoptions.get('makeprivate', False): # pragma: no cover
privacy = 'hidden'
elif workoutsource != 'strava':
privacy = 'visible'
else:
else: # pragma: no cover
privacy = 'hidden'
# checking for in values
@@ -378,7 +378,7 @@ def update_workout_attributes(w, row, file_path, uploadoptions,
try:
workoutenddatetime = startdatetime+delta
except AttributeError as e:
except AttributeError as e: # pragma: no cover
workoutstartdatetime = pendulum.parse(str(startdatetime))
workoutenddatetime = startdatetime+delta
@@ -386,7 +386,7 @@ def update_workout_attributes(w, row, file_path, uploadoptions,
# check for duplicate start times and duration
duplicate = checkduplicates(
w.user, startdate, startdatetime, workoutenddatetime)
if duplicate:
if duplicate: # pragma: no cover
rankingpiece = False
# test title length
@@ -431,7 +431,7 @@ def update_workout_attributes(w, row, file_path, uploadoptions,
w.save()
# check for registrationid
if registrationid != 0:
if registrationid != 0: # pragma: no cover
races = VirtualRace.objects.filter(
registration_closure__gt=tz.now(),
id=raceid,
@@ -495,11 +495,11 @@ def update_running_wps(r, w, row):
duplicate=False).count()
new_value = (cntr*r.running_wps_erg + row.df['driveenergy'].mean())/(cntr+1.0)
# if new_value is not zero or infinite or -inf, r.running_wps can be set to value
if not (math.isnan(new_value) or math.isinf(new_value) or new_value == 0):
if not (math.isnan(new_value) or math.isinf(new_value) or new_value == 0): # pragma: no cover
r.running_wps_erg = new_value
elif not (math.isnan(r.running_wps_erg) or math.isinf(r.running_wps_erg) or r.running_wps_erg == 0):
pass
else:
else: # pragma: no cover
r.running_wps_erg = 600.
r.save()
@@ -509,13 +509,13 @@ def update_running_wps(r, w, row):
duplicate=False).count()
try:
new_value = (cntr*r.running_wps_erg + row.df['driveenergy'].mean())/(cntr+1.0)
except TypeError:
except TypeError: # pragma: no cover
new_value = r.running_wps
if not (math.isnan(new_value) or math.isinf(new_value) or new_value == 0):
r.running_wps = new_value
elif not (math.isnan(r.running_wps) or math.isinf(r.running_wps) or r.running_wps == 0):
pass
else:
else: # pragma: no cover
r.running_wps = 400.
r.save()
@@ -531,7 +531,7 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
f1 = uuid4().hex[:10]+'-'+strftime('%Y%m%d-%H%M%S')+ext
f2 = 'media/'+f1
copyfile(file_path, f2)
except FileNotFoundError:
except FileNotFoundError: # pragma: no cover
return {
"status": "error",
"job_id": job_id,
@@ -540,7 +540,7 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
# determine the user
r = get_rower_from_uploadoptions(uploadoptions)
if r is None:
if r is None: # pragma: no cover
os.remove(f2)
return {
"status": "error",
@@ -550,7 +550,7 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
try:
fileformat = get_file_type(f2)
except Exception as e:
except Exception as e: # pragma: no cover
os.remove(f2)
return {
"status": "error",
@@ -559,16 +559,17 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
}
# Get fileformat from fit & tcx
if fileformat == 'fit':
if "fit" in fileformat:
workouttype = get_workouttype_from_fit(f2)
uploadoptions['workouttype'] = workouttype
new_title = get_title_from_fit(f2)
if new_title:
if new_title: # pragma: no cover
uploadoptions['title'] = new_title
new_notes = get_notes_from_fit(f2)
if new_notes:
if new_notes: # pragma: no cover
uploadoptions['notes'] = new_notes
# handle non-Painsled
if fileformat != 'csv':
f2, summary, oarlength, inboard, fileformat, impeller = handle_nonpainsled(
@@ -581,7 +582,7 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
uploadoptions['useImpeller'] = impeller
if uploadoptions['workouttype'] != 'strave':
uploadoptions['workoutsource'] = fileformat
if not f2:
if not f2: # pragma: no cover
return {
"status": "error",
"job_id": job_id,
@@ -600,7 +601,7 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
powerperc=powerperc, powerzones=r.powerzones)
row = rdata(f2, rower=rr)
if row.df.empty:
if row.df.empty: # pragma: no cover
os.remove(f2)
return {
"status": "error",
@@ -608,7 +609,7 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
"message": "No valid data found in the uploaded file."
}
if row == 0:
if row == 0: # pragma: no cover
os.remove(f2)
return {
"status": "error",
@@ -639,7 +640,7 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
pass
workoutid = uploadoptions.get('id', None)
if workoutid is not None:
if workoutid is not None: # pragma: no cover
try:
w = Workout.objects.get(id=workoutid)
except Workout.DoesNotExist:
@@ -657,7 +658,7 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
if w.privacy == 'visible':
ts = Team.objects.filter(rower=r
)
for t in ts:
for t in ts: # pragma: no cover
w.team.add(t)
# put stroke data in file store through "dataplep"
@@ -686,14 +687,14 @@ def process_single_file(file_path, uploadoptions, job_id, debug=False, **kwargs)
wps_avg = r.median_wps
elif w.workouttype in otetypes:
wps_avg = r.median_wps_erg
else:
else: # pragma: no cover
wps_avg = 0
_ = myqueue(queuehigh, handle_calctrimp, w.id, f2,
r.ftp, r.sex, r.hrftp, r.max, r.rest, wps_avg)
# make plots
if uploadoptions.get('makeplot', False):
if uploadoptions.get('makeplot', False): # pragma: no cover
plottype = uploadoptions.get('plottype', 'timeplot')
res, jobid = uploads.make_plot(r, w, f1, f2, plottype, w.name)
elif r.staticchartonupload != 'None': # pragma: no cover

View File

@@ -7,11 +7,47 @@ from __future__ import unicode_literals
from .statements import *
nu = datetime.datetime.now()
from django.db import transaction
import shutil
from rowers.views import add_defaultfavorites
from rowers.dataflow import process_single_file, upload_handler, unzip_and_process
from django.core.files.uploadedfile import SimpleUploadedFile
from django.conf import settings
from rowingdata import get_file_type
file_list = [
'rowers/tests/testdata/testdata.csv',
'rowers/tests/testdata/testdata.csv.gz',
'rowers/tests/testdata/tim.csv',
'rowers/tests/testdata/crewnerddata.tcx',
'rowers/tests/testdata/Speedcoach2example.csv',
'rowers/tests/testdata/Impeller.csv',
'rowers/tests/testdata/speedcoach3test3.csv',
'rowers/tests/testdata/SpeedCoach2Linkv1.27.csv',
'rowers/tests/testdata/SpeedCoach2Link_interval.csv',
'rowers/tests/testdata/NoHR.tcx',
'rowers/tests/testdata/rowinginmotionexample.tcx',
'rowers/tests/testdata/RP_testdata.csv',
'rowers/tests/testdata/mystery.csv',
'rowers/tests/testdata/RP_interval.csv',
'rowers/tests/testdata/3x250m.fit',
'rowers/tests/testdata/painsled_desktop_example.csv',
'rowers/tests/testdata/ergdata_example.csv',
'rowers/tests/testdata/boatcoach_2021-09-09__18-15-53.csv',
'rowers/tests/testdata/colinforce.csv',
'rowers/tests/testdata/PainsledForce.csv',
'rowers/tests/testdata/EmpowerSpeedCoachForce.csv',
'rowers/tests/testdata/boatcoach.csv',
'rowers/tests/testdata/ergstick.csv',
]
fail_list = [
'rowers/tests/testdata/lofoten.jpg',
'rowers/tests/testdata/c2records.json',
'rowers/tests/testdata/alphen.kml',
'rowers/tests/testdata/testdata.gpx'
]
#@pytest.mark.django_db
@override_settings(TESTING=True)
@@ -31,28 +67,29 @@ class ViewTest(TestCase):
self.nu = datetime.datetime.now()
file_list = ['rowers/tests/testdata/testdata.csv',
'rowers/tests/testdata/tim.csv',
'rowers/tests/testdata/crewnerddata.tcx',
'rowers/tests/testdata/Speedcoach2example.csv',
'rowers/tests/testdata/Impeller.csv',
'rowers/tests/testdata/speedcoach3test3.csv',
'rowers/tests/testdata/SpeedCoach2Linkv1.27.csv',
'rowers/tests/testdata/SpeedCoach2Link_interval.csv',
'rowers/tests/testdata/NoHR.tcx',
'rowers/tests/testdata/rowinginmotionexample.tcx',
'rowers/tests/testdata/RP_testdata.csv',
'rowers/tests/testdata/mystery.csv',
'rowers/tests/testdata/RP_interval.csv',
'rowers/tests/testdata/painsled_desktop_example.csv',
'rowers/tests/testdata/ergdata_example.csv',
'rowers/tests/testdata/boatcoach_2021-09-09__18-15-53.csv',
'rowers/tests/testdata/colinforce.csv',
'rowers/tests/testdata/PainsledForce.csv',
'rowers/tests/testdata/EmpowerSpeedCoachForce.csv',
'rowers/tests/testdata/boatcoach.csv',
'rowers/tests/testdata/ergstick.csv',
]
# copy every file in fail_list to rowers/tests/testdata/backup folder
# Zorg ervoor dat de backup-map bestaat
backup_dir = 'rowers/tests/testdata/backup'
os.makedirs(backup_dir, exist_ok=True)
# Kopieer elk bestand in fail_list naar de backup-map
for file_path in fail_list:
if os.path.exists(file_path):
shutil.copy(file_path, backup_dir)
else:
print(f"Bestand niet gevonden: {file_path}")
def tearDown(self):
backup_dir = 'rowers/tests/testdata/backup'
for file_path in fail_list:
backup_file = os.path.join(backup_dir, os.path.basename(file_path))
if os.path.exists(backup_file):
shutil.copy(backup_file, os.path.dirname(file_path))
else:
print(f"Backup-bestand niet gevonden: {backup_file}")
@parameterized.expand(file_list)
@patch('rowers.dataflow.myqueue')
def test_upload_view(self, filename, mocked_myqueue):
@@ -93,12 +130,62 @@ class ViewTest(TestCase):
response = self.c.post('/rowers/workout/upload/', data = form_data,
files = {'file': uploaded_file}, follow=True)
self.assertEqual(response.status_code, 200)
uploadoptions = form.cleaned_data.copy()
uploadoptions.update(optionsform.cleaned_data)
result = upload_handler(uploadoptions, filename)
self.assertEqual(result["status"], "processing")
@parameterized.expand(fail_list)
@patch('rowers.dataflow.myqueue')
def test_upload_view(self, filename, mocked_myqueue):
# simple test to see if upload view works. Submits a DocumentsForm to /rowers/workout/upload/
login = self.c.login(username='john',password='koeinsloot')
self.assertTrue(login)
with open(filename, 'rb') as f:
file_content = f.read()
uploaded_file = SimpleUploadedFile(
"testdata.csv",
file_content,
content_type="text/csv"
)
form_data = {
'title':'test',
'workouttype':'rower',
'boattype':'1x',
'notes':'aap noot mies',
'make_plot':False,
'rpe':6,
'upload_to_c2':False,
'plottype':'timeplot',
'landingpage':'workout_edit_view',
'raceid':0,
'file': filename,
}
request = RequestFactory()
request.user = self.u
form = DocumentsForm(data = form_data,files={'file': uploaded_file})
self.assertTrue(form.is_valid())
optionsform = UploadOptionsForm(form_data,request=request)
self.assertTrue(optionsform.is_valid())
response = self.c.post('/rowers/workout/upload/', data = form_data,
files = {'file': uploaded_file}, follow=True)
self.assertEqual(response.status_code, 200)
uploadoptions = form.cleaned_data.copy()
uploadoptions.update(optionsform.cleaned_data)
result = upload_handler(uploadoptions, filename)
self.assertEqual(result["status"], "error")
@parameterized.expand(file_list)
@patch('rowers.dataflow.myqueue')
def test_process_single_file(self, filename, mocked_myqueue):
@@ -120,6 +207,75 @@ class ViewTest(TestCase):
self.assertEqual(result, True)
os.remove(f2+'.gz')
# process a single file without 'user'
@patch('rowers.dataflow.myqueue')
def test_process_single_file_nouser(self, mocked_myqueue):
filename = 'rowers/tests/testdata/testdata.csv'
uploadoptions = {
'title':'test',
'workouttype':'rower',
'boattype':'1x',
'notes':'aap noot mies',
'make_plot':False,
'rpe':6,
'upload_to_c2':False,
'plottype':'timeplot',
'landingpage':'workout_edit_view',
'raceid':0,
'useremail': self.u.email,
'file': filename,
}
result, f2 = process_single_file(filename, uploadoptions, 1)
self.assertEqual(result, True)
os.remove(f2+'.gz')
# process a zip file
@patch('rowers.dataflow.myqueue')
def test_process_single_zipfile(self, mocked_myqueue):
filename = 'rowers/tests/testdata/zipfile.zip'
uploadoptions = {
'title':'test',
'workouttype':'rower',
'boattype':'1x',
'notes':'aap noot mies',
'make_plot':False,
'rpe':6,
'upload_to_c2':False,
'plottype':'timeplot',
'landingpage':'workout_edit_view',
'raceid':0,
'user': self.u,
'file': filename,
}
result = process_single_file(filename, uploadoptions, 1)
self.assertEqual(result["status"], "error")
result = upload_handler(uploadoptions, filename)
self.assertEqual(result["status"], "processing")
# process a single file without 'title'
@patch('rowers.dataflow.myqueue')
def test_process_single_file_nouser(self, mocked_myqueue):
filename = 'rowers/tests/testdata/testdata.csv'
uploadoptions = {
'workouttype':'rower',
'boattype':'1x',
'notes':'aap noot mies',
'make_plot':False,
'rpe':6,
'upload_to_c2':False,
'plottype':'timeplot',
'landingpage':'workout_edit_view',
'raceid':0,
'user': self.u,
'file': filename,
}
result, f2 = process_single_file(filename, uploadoptions, 1)
self.assertEqual(result, True)
os.remove(f2+'.gz')
@patch('rowers.dataflow.myqueue')
def test_process_zip_file(self, mocked_myqueue):
filename = 'rowers/tests/testdata/zipfile.zip'

178
rowers/tests/testdata/backup/alphen.kml vendored Normal file
View File

@@ -0,0 +1,178 @@
<?xml version="1.0" ?>
<kml xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.google.com/kml/ext/2.2" xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Courses.kml</name>
<Folder>
<name>Courses</name>
<Folder>
<name>Alphen - Alphen aan den Rijn</name>
<open>1</open>
<Placemark>
<name>Start</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.704149601313898,52.14611068342334,0 4.704648516706039,52.14606840788696,0 4.704642182077736,52.14626893773362,0 4.704151599747837,52.14628828501986,0 4.704149601313898,52.14611068342334,0 4.704149601313898,52.14611068342334,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 1</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.704040567073562,52.14772365703576,0 4.704544185247905,52.14767250842382,0 4.704570221164488,52.14791407188889,0 4.704130359234369,52.14797079566858,0 4.704040567073562,52.14772365703576,0 4.704040567073562,52.14772365703576,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 2</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.707120374629225,52.15459940303027,0 4.707573702026327,52.15460568431943,0 4.70761596147063,52.15486728249238,0 4.707159504658982,52.15489881627455,0 4.707120374629225,52.15459940303027,0 4.707120374629225,52.15459940303027,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 3</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.709028668490356,52.1646474322453,0 4.70984931790314,52.16449178436365,0 4.709978566943311,52.16488586779201,0 4.709244456319242,52.16499245615274,0 4.709028668490356,52.1646474322453,0 4.709028668490356,52.1646474322453,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 4</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.718138359290078,52.17865355742074,0 4.718653235056161,52.17830639665007,0 4.719134204848634,52.17862031168055,0 4.71867160984541,52.17894003397144,0 4.718138359290078,52.17865355742074,0 4.718138359290078,52.17865355742074,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 5</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.727641648412835,52.18284846695732,0 4.728273789904367,52.18251973845241,0 4.728577606945771,52.1827641768111,0 4.7279847617705,52.1830837392454,0 4.727641648412835,52.18284846695732,0 4.727641648412835,52.18284846695732,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 6</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.738716857017891,52.19396028458393,0 4.739294818571407,52.19389560588872,0 4.739411118817641,52.19428660874426,0 4.738864571028594,52.19431307372239,0 4.738716857017891,52.19396028458393,0 4.738716857017891,52.19396028458393,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 7</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.734183821236371,52.20620514880871,0 4.734924962205387,52.20637199686158,0 4.734802543714663,52.20688025274802,0 4.733601274999542,52.20663721340052,0 4.734183821236371,52.20620514880871,0 4.734183821236371,52.20620514880871,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 8</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.738785303605908,52.19457123452171,0 4.739333350356509,52.19459196501802,0 4.739304304831564,52.19482691469288,0 4.73885420703549,52.19479878738656,0 4.738785303605908,52.19457123452171,0 4.738785303605908,52.19457123452171,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 9</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.728292586661338,52.18327969510192,0 4.728884338045631,52.18302182842039,0 4.729083849790216,52.1833152834237,0 4.728606271720666,52.18355598784883,0 4.728292586661338,52.18327969510192,0 4.728292586661338,52.18327969510192,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 10</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.717008631662971,52.17788756203277,0 4.717714777374475,52.17758571819474,0 4.718168595226933,52.17803093936305,0 4.717634575621297,52.17832999894938,0 4.717008631662971,52.17788756203277,0 4.717008631662971,52.17788756203277,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 11</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.708580146922809,52.16405851453961,0 4.709467162927956,52.16392338577828,0 4.709761923185198,52.16427786809471,0 4.708922971852094,52.16448915385681,0 4.708580146922809,52.16405851453961,0 4.708580146922809,52.16405851453961,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 12</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.70716800510311,52.15500418035832,0 4.707671825192278,52.15498496004398,0 4.707743878685751,52.15525628533189,0 4.707149393888881,52.1553218720998,0 4.70716800510311,52.15500418035832,0 4.70716800510311,52.15500418035832,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Gate 13</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.704140681716737,52.14813498986593,0 4.704864196194787,52.1479883822655,0 4.705153909432487,52.14838874308533,0 4.704223464041033,52.14854260247372,0 4.704140681716737,52.14813498986593,0 4.704140681716737,52.14813498986593,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Finish</name>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>4.70414987291546,52.1461319705247,0 4.704561170436561,52.14607111930849,0 4.704642182077736,52.14626893773362,0 4.70415735390207,52.14628831020436,0 4.70414987291546,52.1461319705247,0 4.70414987291546,52.1461319705247,0</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Folder>
</Folder>
</Document>
</kml>

BIN
rowers/tests/testdata/backup/lofoten.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

View File

@@ -0,0 +1,574 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" creator="Oregon 400t" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"><metadata><link href="http://www.garmin.com"><text>Garmin International</text></link><time>2016-05-20T15:41:26</time></metadata><trk><name>Export by rowingdata</name><trkseg> <trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:26+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:29.238150+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:32.148290+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:35.269000+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:38.152180+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:41.148270+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:44.148910+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:46.908250+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:49.819010+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:52.942510+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:55.639670+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:41:58.370000+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:01.188270+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:04.008300+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:06.888990+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:09.678900+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:12.469140+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:15.199010+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:17.963080+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:20.658340+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:23.538800+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:26.269790+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:28.848350+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:31.729550+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:34.398400+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:37.038360+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:39.499250+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:42.349070+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:45.079070+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:47.752890+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:50.452350+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:53.182630+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:55.789410+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:42:58.671890+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:01.338860+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:04.068490+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:06.862620+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:09.618500+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:12.379160+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:15.229200+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:17.963150+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:20.692490+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:23.628520+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:26.329210+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:29.148960+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:31.668570+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:34.490920+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:37.369250+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:40.189230+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:42.798860+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:45.708750+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:48.318590+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:51.199500+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:53.869290+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:56.572490+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:43:59.212410+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:01.912890+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:04.459350+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:07.249360+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:09.949930+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:12.619870+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:15.378800+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:18.049420+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:20.719440+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:23.298970+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:26.178820+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:28.669980+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:31.429270+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:34.042790+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:36.589070+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:39.412800+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:42.078870+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:44.783760+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:47.450710+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:50.149400+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:52.789720+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:55.429750+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:44:58.069700+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:00.742790+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:03.442700+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:06.139610+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:08.689490+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:11.479530+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:14.119610+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:16.792860+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:19.368950+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:22.158960+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:24.889580+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:27.558940+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:30.469760+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:33.259860+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:36.079590+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:38.899560+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:41.689980+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:44.568940+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:47.329670+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:50.149560+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:52.969660+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:55.879910+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:45:58.789690+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:01.729660+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:04.669610+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:07.549730+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:10.458930+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:13.488980+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:16.429320+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:19.519650+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:22.459630+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:25.338880+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:28.459530+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:31.401590+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:34.339560+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:37.309450+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:40.098920+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:43.039950+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:46.039490+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:48.979630+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:51.949590+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:54.709590+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:46:57.589710+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:00.503120+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:03.408950+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:06.323410+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:09.229670+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:12.198960+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:15.079930+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:17.989660+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:20.959680+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:23.869730+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:26.782970+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:29.688910+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:32.539570+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:35.449720+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:38.329080+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:41.148960+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:44.088880+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:47.150600+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:50.029750+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:52.998850+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:55.880360+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:47:58.789400+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:01.639760+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:04.492770+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:07.429530+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:10.373270+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:13.309500+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:16.279570+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:19.160740+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:21.948820+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:25.039520+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:27.949340+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:30.890880+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:33.648790+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:36.770050+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:39.499600+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:42.559140+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:45.439020+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:48.439810+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:51.379570+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:54.259600+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:48:57.139300+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:00.049550+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:02.838790+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:05.839540+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:08.749400+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:11.689540+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:14.538900+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:17.389440+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:20.058880+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:23.059530+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:25.880610+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:28.608730+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:31.582600+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:34.278700+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:37.068660+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:40.039460+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:42.889790+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:45.772580+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:48.708690+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:51.679450+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:54.499470+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:49:57.409440+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:00.439330+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:03.408680+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:06.378680+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:09.168860+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:12.229650+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:15.138650+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:18.049470+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:20.959460+00:00</time>
</trkpt>
<trkpt lat="0.0" lon="0.0">
<time>2016-05-20T13:50:23.242360+00:00</time>
</trkpt>
</trkseg></trk></gpx>

Binary file not shown.