init - v1

This commit is contained in:
friedemann.blume 2024-07-21 14:10:43 +02:00
commit 8c1ad7ebdf
10 changed files with 1800 additions and 0 deletions

38
Dockerfile Normal file
View File

@ -0,0 +1,38 @@
FROM debian:bookworm-slim
# Install system dependencies
RUN apt-get update && apt-get install -y \
python3 \
python3-venv \
python3-pip \
gpsbabel \
&& rm -rf /var/lib/apt/lists/*
# Set up app directory
WORKDIR /app
# Copy application files
COPY app.py /app/
COPY templates /app/templates
COPY requirements.txt /app/
# Create and activate virtual environment
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
# Install Python dependencies in virtual environment
RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt
# Create input and output directories
RUN mkdir /app/input /app/output
# Set environment variables
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
# Expose port
EXPOSE 5000
# Run the application
CMD ["python", "-m", "flask", "run"]

82
Readme.md Normal file
View File

@ -0,0 +1,82 @@
# FIT to GPX Converter
FIT to GPX Converter is a web application that allows users to easily convert Garmin FIT (Flexible and Interoperable Data Transfer) files to GPX (GPS Exchange Format) files. This tool is particularly useful for athletes, outdoor enthusiasts, and anyone who needs to convert their fitness tracking data from FIT to the more widely compatible GPX format.
## Features
- Upload FIT files through a user-friendly web interface
- Automatic conversion of FIT files to GPX format
- View and manage both input (FIT) and output (GPX) files
- Select and delete multiple files
- Responsive design for both desktop and mobile use
- Auto-refresh to show newly converted files
## Prerequisites
Before you begin, ensure you have met the following requirements:
- Docker and Docker Compose installed on your system
- Git for cloning the repository
## Installation
To install FIT to GPX Converter, follow these steps:
1. Clone the repository:
```
git clone https://github.com/your-username/fit-to-gpx-converter.git
cd fit-to-gpx-converter
```
2. Build the Docker image:
```
docker-compose build
```
3. Start the application:
```
docker-compose up
```
The application should now be running and accessible at `http://localhost:5000`.
## Usage
1. Open your web browser and navigate to `http://localhost:5000`.
2. Use the file input to select and upload a .fit file.
3. Click the "Upload and Convert" button.
4. Wait for the conversion process to complete.
5. The converted .gpx file will appear in the "Output Files" list.
6. Click on the file name in the "Output Files" list to download the converted .gpx file.
### Managing Files
- To delete input or output files, select the checkboxes next to the files you wish to remove, then click the "Delete Selected Files" button for the respective list.
- The page automatically refreshes every 30 seconds to show newly converted files.
## Contributing
Contributions to the FIT to GPX Converter are welcome. Please follow these steps to contribute:
1. Fork the repository.
2. Create a new branch: `git checkout -b <branch_name>`.
3. Make your changes and commit them: `git commit -m '<commit_message>'`
4. Push to the original branch: `git push origin <project_name>/<location>`
5. Create the pull request.
Alternatively, see the GitHub documentation on [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
## License
This project uses the following license: [MIT License](https://opensource.org/licenses/MIT).
## Contact
If you want to contact the maintainer of this project, please email [your-email@example.com](mailto:your-email@example.com).
## Acknowledgements
- [Flask](https://flask.palletsprojects.com/) - The web framework used
- [GPSBabel](https://www.gpsbabel.org/) - Used for file conversion
- [Tailwind CSS](https://tailwindcss.com/) - Used for styling
- [Alpine.js](https://alpinejs.dev/) - Used for interactive elements

71
app.py Normal file
View File

@ -0,0 +1,71 @@
import os
from flask import Flask, request, render_template, send_from_directory, redirect, url_for, flash, jsonify
import subprocess
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.secret_key = 'your_secret_key_here' # Required for flash messaging
INPUT_FOLDER = '/app/input'
OUTPUT_FOLDER = '/app/output'
ALLOWED_EXTENSIONS = {'fit'}
app.config['INPUT_FOLDER'] = INPUT_FOLDER
app.config['OUTPUT_FOLDER'] = OUTPUT_FOLDER
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
flash('No file part', 'error')
return redirect(url_for('upload_file'))
file = request.files['file']
if file.filename == '':
flash('No selected file', 'error')
return redirect(url_for('upload_file'))
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
input_path = os.path.join(app.config['INPUT_FOLDER'], filename)
file.save(input_path)
output_filename = f"{os.path.splitext(filename)[0]}.gpx"
output_path = os.path.join(app.config['OUTPUT_FOLDER'], output_filename)
subprocess.run(['gpsbabel', '-i', 'garmin_fit', '-f', input_path, '-o', 'gpx', '-F', output_path])
flash('File uploaded and converted successfully', 'success')
return redirect(url_for('upload_file'))
else:
flash('Invalid file type. Please upload a .fit file.', 'error')
return redirect(url_for('upload_file'))
input_files = os.listdir(app.config['INPUT_FOLDER'])
output_files = os.listdir(app.config['OUTPUT_FOLDER'])
return render_template('index.html', input_files=input_files, output_files=output_files)
@app.route('/download/<filename>')
def download_file(filename):
return send_from_directory(app.config['OUTPUT_FOLDER'], filename, as_attachment=True)
@app.route('/delete', methods=['POST'])
def delete_files():
files_to_delete = request.json.get('files', [])
folder = request.json.get('folder', '')
if folder not in ['input', 'output']:
return jsonify({'error': 'Invalid folder specified'}), 400
target_folder = app.config['INPUT_FOLDER'] if folder == 'input' else app.config['OUTPUT_FOLDER']
for filename in files_to_delete:
file_path = os.path.join(target_folder, filename)
if os.path.exists(file_path):
os.remove(file_path)
return jsonify({'message': 'Files deleted successfully'}), 200
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

8
docker-compose.yml Normal file
View File

@ -0,0 +1,8 @@
services:
fit2gpx:
image: fit2gpx
ports:
- "5001:5000"
volumes:
- ./input:/app/input
- ./output:/app/output

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,720 @@
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
<time>2024-07-21T12:06:53.317Z</time>
<bounds minlat="51.439850908" minlon="7.337710569" maxlat="51.451868126" maxlon="7.353162607"/>
<wpt lat="51.451868126" lon="7.353162607">
<name>LAP001</name>
<cmt>LAP001</cmt>
<desc>LAP001</desc>
</wpt>
<trk>
<trkseg>
<trkpt lat="51.439850908" lon="7.337710569">
<ele>119.800</ele>
<time>2024-04-19T15:39:35Z</time>
<speed>4.180000</speed>
</trkpt>
<trkpt lat="51.439859373" lon="7.337758429">
<ele>120.600</ele>
<time>2024-04-19T15:39:36Z</time>
<speed>5.141000</speed>
</trkpt>
<trkpt lat="51.439870521" lon="7.337796567">
<ele>121.400</ele>
<time>2024-04-19T15:39:37Z</time>
<speed>4.637000</speed>
</trkpt>
<trkpt lat="51.439893320" lon="7.337844176">
<ele>122.000</ele>
<time>2024-04-19T15:39:38Z</time>
<speed>5.141000</speed>
</trkpt>
<trkpt lat="51.439915448" lon="7.337889271">
<ele>122.200</ele>
<time>2024-04-19T15:39:39Z</time>
<speed>4.637000</speed>
</trkpt>
<trkpt lat="51.440054253" lon="7.338157911">
<ele>123.800</ele>
<time>2024-04-19T15:39:45Z</time>
<speed>3.938000</speed>
</trkpt>
<trkpt lat="51.440120386" lon="7.338287160">
<ele>124.200</ele>
<time>2024-04-19T15:39:48Z</time>
<speed>3.919000</speed>
</trkpt>
<trkpt lat="51.440152321" lon="7.338379361">
<ele>124.600</ele>
<time>2024-04-19T15:39:50Z</time>
<speed>3.919000</speed>
</trkpt>
<trkpt lat="51.440188782" lon="7.338427138">
<ele>124.800</ele>
<time>2024-04-19T15:39:51Z</time>
<speed>5.160000</speed>
</trkpt>
<trkpt lat="51.440219879" lon="7.338528726">
<ele>125.000</ele>
<time>2024-04-19T15:39:53Z</time>
<speed>5.440000</speed>
</trkpt>
<trkpt lat="51.440207222" lon="7.338673985">
<ele>125.000</ele>
<time>2024-04-19T15:39:56Z</time>
<speed>3.228000</speed>
</trkpt>
<trkpt lat="51.440201020" lon="7.338737436">
<ele>125.200</ele>
<time>2024-04-19T15:39:57Z</time>
<speed>4.731000</speed>
</trkpt>
<trkpt lat="51.440191548" lon="7.338812286">
<ele>125.200</ele>
<time>2024-04-19T15:39:58Z</time>
<speed>4.731000</speed>
</trkpt>
<trkpt lat="51.440179562" lon="7.338876491">
<ele>125.200</ele>
<time>2024-04-19T15:39:59Z</time>
<speed>4.721000</speed>
</trkpt>
<trkpt lat="51.440145448" lon="7.338938937">
<ele>125.200</ele>
<time>2024-04-19T15:40:00Z</time>
<speed>4.385000</speed>
</trkpt>
<trkpt lat="51.440114519" lon="7.338999622">
<ele>125.600</ele>
<time>2024-04-19T15:40:01Z</time>
<speed>4.721000</speed>
</trkpt>
<trkpt lat="51.440088702" lon="7.339055697">
<ele>125.800</ele>
<time>2024-04-19T15:40:02Z</time>
<speed>4.563000</speed>
</trkpt>
<trkpt lat="51.440070430" lon="7.339176144">
<ele>126.000</ele>
<time>2024-04-19T15:40:04Z</time>
<speed>4.339000</speed>
</trkpt>
<trkpt lat="51.440065317" lon="7.339243786">
<ele>126.000</ele>
<time>2024-04-19T15:40:05Z</time>
<speed>4.385000</speed>
</trkpt>
<trkpt lat="51.440071771" lon="7.339308998">
<ele>126.200</ele>
<time>2024-04-19T15:40:06Z</time>
<speed>4.563000</speed>
</trkpt>
<trkpt lat="51.440121727" lon="7.339429613">
<ele>126.200</ele>
<time>2024-04-19T15:40:08Z</time>
<speed>4.563000</speed>
</trkpt>
<trkpt lat="51.440243516" lon="7.339740247">
<ele>126.200</ele>
<time>2024-04-19T15:40:13Z</time>
<speed>4.964000</speed>
</trkpt>
<trkpt lat="51.440272685" lon="7.339856001">
<ele>126.400</ele>
<time>2024-04-19T15:40:15Z</time>
<speed>4.964000</speed>
</trkpt>
<trkpt lat="51.440295987" lon="7.339909142">
<ele>126.400</ele>
<time>2024-04-19T15:40:16Z</time>
<speed>4.964000</speed>
</trkpt>
<trkpt lat="51.440370167" lon="7.339986339">
<ele>126.600</ele>
<time>2024-04-19T15:40:18Z</time>
<speed>5.048000</speed>
</trkpt>
<trkpt lat="51.440430768" lon="7.340011485">
<ele>126.600</ele>
<time>2024-04-19T15:40:19Z</time>
<speed>5.645000</speed>
</trkpt>
<trkpt lat="51.440665880" lon="7.340106284">
<ele>126.800</ele>
<time>2024-04-19T15:40:23Z</time>
<speed>6.457000</speed>
</trkpt>
<trkpt lat="51.441054549" lon="7.340181554">
<ele>126.000</ele>
<time>2024-04-19T15:40:30Z</time>
<speed>5.766000</speed>
</trkpt>
<trkpt lat="51.441132082" lon="7.340197731">
<ele>126.200</ele>
<time>2024-04-19T15:40:32Z</time>
<speed>5.048000</speed>
</trkpt>
<trkpt lat="51.441200646" lon="7.340212148">
<ele>126.400</ele>
<time>2024-04-19T15:40:34Z</time>
<speed>3.891000</speed>
</trkpt>
<trkpt lat="51.441239370" lon="7.340219691">
<ele>126.600</ele>
<time>2024-04-19T15:40:35Z</time>
<speed>4.507000</speed>
</trkpt>
<trkpt lat="51.441495270" lon="7.340295715">
<ele>126.400</ele>
<time>2024-04-19T15:40:40Z</time>
<speed>5.757000</speed>
</trkpt>
<trkpt lat="51.441592751" lon="7.340324298">
<ele>126.400</ele>
<time>2024-04-19T15:40:42Z</time>
<speed>5.113000</speed>
</trkpt>
<trkpt lat="51.441661986" lon="7.340402249">
<ele>127.600</ele>
<time>2024-04-19T15:40:45Z</time>
<speed>5.496000</speed>
</trkpt>
<trkpt lat="51.441757539" lon="7.340433933">
<ele>128.200</ele>
<time>2024-04-19T15:40:47Z</time>
<speed>5.570000</speed>
</trkpt>
<trkpt lat="51.441806406" lon="7.340448266">
<ele>128.600</ele>
<time>2024-04-19T15:40:48Z</time>
<speed>5.141000</speed>
</trkpt>
<trkpt lat="51.441852925" lon="7.340464527">
<ele>129.000</ele>
<time>2024-04-19T15:40:49Z</time>
<speed>5.095000</speed>
</trkpt>
<trkpt lat="51.441968847" lon="7.340519764">
<ele>129.200</ele>
<time>2024-04-19T15:40:52Z</time>
<speed>4.059000</speed>
</trkpt>
<trkpt lat="51.442094408" lon="7.340598721">
<ele>129.400</ele>
<time>2024-04-19T15:40:57Z</time>
<speed>2.118000</speed>
</trkpt>
<trkpt lat="51.442106897" lon="7.340609031">
<ele>129.400</ele>
<time>2024-04-19T15:40:58Z</time>
<speed>1.903000</speed>
</trkpt>
<trkpt lat="51.442109244" lon="7.340612384">
<ele>129.600</ele>
<time>2024-04-19T15:41:00Z</time>
<speed>0.000000</speed>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="51.442138581" lon="7.340643397">
<ele>130.400</ele>
<time>2024-04-19T15:41:18Z</time>
<speed>2.762000</speed>
</trkpt>
<trkpt lat="51.442167750" lon="7.340665106">
<ele>130.400</ele>
<time>2024-04-19T15:41:19Z</time>
<speed>3.256000</speed>
</trkpt>
<trkpt lat="51.442253580" lon="7.340805922">
<ele>129.800</ele>
<time>2024-04-19T15:41:22Z</time>
<speed>4.152000</speed>
</trkpt>
<trkpt lat="51.442441503" lon="7.341097696">
<ele>130.200</ele>
<time>2024-04-19T15:41:28Z</time>
<speed>5.179000</speed>
</trkpt>
<trkpt lat="51.442562537" lon="7.341218647">
<ele>131.200</ele>
<time>2024-04-19T15:41:31Z</time>
<speed>5.272000</speed>
</trkpt>
<trkpt lat="51.442622216" lon="7.341294922">
<ele>131.800</ele>
<time>2024-04-19T15:41:33Z</time>
<speed>5.179000</speed>
</trkpt>
<trkpt lat="51.442715675" lon="7.341361055">
<ele>131.800</ele>
<time>2024-04-19T15:41:35Z</time>
<speed>5.281000</speed>
</trkpt>
<trkpt lat="51.443042485" lon="7.341584349">
<ele>131.400</ele>
<time>2024-04-19T15:41:42Z</time>
<speed>5.552000</speed>
</trkpt>
<trkpt lat="51.443139045" lon="7.341655428">
<ele>130.800</ele>
<time>2024-04-19T15:41:44Z</time>
<speed>5.552000</speed>
</trkpt>
<trkpt lat="51.443190342" lon="7.341679819">
<ele>130.600</ele>
<time>2024-04-19T15:41:45Z</time>
<speed>5.552000</speed>
</trkpt>
<trkpt lat="51.443344066" lon="7.341751819">
<ele>129.600</ele>
<time>2024-04-19T15:41:48Z</time>
<speed>5.636000</speed>
</trkpt>
<trkpt lat="51.443392932" lon="7.341790628">
<ele>129.400</ele>
<time>2024-04-19T15:41:49Z</time>
<speed>5.636000</speed>
</trkpt>
<trkpt lat="51.443494018" lon="7.341874782">
<ele>129.000</ele>
<time>2024-04-19T15:41:51Z</time>
<speed>5.710000</speed>
</trkpt>
<trkpt lat="51.443593679" lon="7.341991207">
<ele>129.000</ele>
<time>2024-04-19T15:41:53Z</time>
<speed>6.466000</speed>
</trkpt>
<trkpt lat="51.443946054" lon="7.342397142">
<ele>128.600</ele>
<time>2024-04-19T15:42:00Z</time>
<speed>6.485000</speed>
</trkpt>
<trkpt lat="51.444090139" lon="7.342580119">
<ele>128.400</ele>
<time>2024-04-19T15:42:03Z</time>
<speed>6.597000</speed>
</trkpt>
<trkpt lat="51.444179155" lon="7.342711044">
<ele>128.400</ele>
<time>2024-04-19T15:42:05Z</time>
<speed>6.541000</speed>
</trkpt>
<trkpt lat="51.444466654" lon="7.343319403">
<ele>127.400</ele>
<time>2024-04-19T15:42:13Z</time>
<speed>6.494000</speed>
</trkpt>
<trkpt lat="51.444621300" lon="7.343737157">
<ele>127.400</ele>
<time>2024-04-19T15:42:18Z</time>
<speed>6.597000</speed>
</trkpt>
<trkpt lat="51.444636304" lon="7.343820222">
<ele>127.400</ele>
<time>2024-04-19T15:42:19Z</time>
<speed>6.597000</speed>
</trkpt>
<trkpt lat="51.444651559" lon="7.343898928">
<ele>127.400</ele>
<time>2024-04-19T15:42:20Z</time>
<speed>6.597000</speed>
</trkpt>
<trkpt lat="51.444710987" lon="7.344032871">
<ele>127.400</ele>
<time>2024-04-19T15:42:22Z</time>
<speed>6.587000</speed>
</trkpt>
<trkpt lat="51.444809223" lon="7.344256667">
<ele>127.200</ele>
<time>2024-04-19T15:42:25Z</time>
<speed>6.364000</speed>
</trkpt>
<trkpt lat="51.444887426" lon="7.344408296">
<ele>126.600</ele>
<time>2024-04-19T15:42:27Z</time>
<speed>6.783000</speed>
</trkpt>
<trkpt lat="51.444924474" lon="7.344482979">
<ele>125.800</ele>
<time>2024-04-19T15:42:28Z</time>
<speed>6.783000</speed>
</trkpt>
<trkpt lat="51.445156652" lon="7.344941888">
<ele>124.800</ele>
<time>2024-04-19T15:42:34Z</time>
<speed>6.765000</speed>
</trkpt>
<trkpt lat="51.445319010" lon="7.345239194">
<ele>124.200</ele>
<time>2024-04-19T15:42:38Z</time>
<speed>6.765000</speed>
</trkpt>
<trkpt lat="51.445359159" lon="7.345314967">
<ele>123.800</ele>
<time>2024-04-19T15:42:39Z</time>
<speed>6.765000</speed>
</trkpt>
<trkpt lat="51.445481284" lon="7.345542032">
<ele>123.600</ele>
<time>2024-04-19T15:42:42Z</time>
<speed>6.877000</speed>
</trkpt>
<trkpt lat="51.445524031" lon="7.345615039">
<ele>123.600</ele>
<time>2024-04-19T15:42:43Z</time>
<speed>6.895000</speed>
</trkpt>
<trkpt lat="51.445778506" lon="7.346052909">
<ele>123.400</ele>
<time>2024-04-19T15:42:49Z</time>
<speed>6.914000</speed>
</trkpt>
<trkpt lat="51.445816895" lon="7.346121892">
<ele>123.400</ele>
<time>2024-04-19T15:42:50Z</time>
<speed>6.914000</speed>
</trkpt>
<trkpt lat="51.445908761" lon="7.346254494">
<ele>123.400</ele>
<time>2024-04-19T15:42:52Z</time>
<speed>6.914000</speed>
</trkpt>
<trkpt lat="51.446038680" lon="7.346459096">
<ele>123.200</ele>
<time>2024-04-19T15:42:55Z</time>
<speed>6.821000</speed>
</trkpt>
<trkpt lat="51.446273541" lon="7.346767550">
<ele>122.600</ele>
<time>2024-04-19T15:43:00Z</time>
<speed>6.662000</speed>
</trkpt>
<trkpt lat="51.446372783" lon="7.346871654">
<ele>122.400</ele>
<time>2024-04-19T15:43:02Z</time>
<speed>6.662000</speed>
</trkpt>
<trkpt lat="51.446426930" lon="7.346916497">
<ele>122.200</ele>
<time>2024-04-19T15:43:03Z</time>
<speed>6.653000</speed>
</trkpt>
<trkpt lat="51.446818952" lon="7.347142724">
<ele>121.600</ele>
<time>2024-04-19T15:43:10Z</time>
<speed>6.653000</speed>
</trkpt>
<trkpt lat="51.446870668" lon="7.347171726">
<ele>121.400</ele>
<time>2024-04-19T15:43:11Z</time>
<speed>6.653000</speed>
</trkpt>
<trkpt lat="51.447020117" lon="7.347244648">
<ele>120.600</ele>
<time>2024-04-19T15:43:14Z</time>
<speed>6.615000</speed>
</trkpt>
<trkpt lat="51.447243327" lon="7.347367611">
<ele>120.400</ele>
<time>2024-04-19T15:43:18Z</time>
<speed>6.615000</speed>
</trkpt>
<trkpt lat="51.447300073" lon="7.347393008">
<ele>120.400</ele>
<time>2024-04-19T15:43:19Z</time>
<speed>6.522000</speed>
</trkpt>
<trkpt lat="51.447787313" lon="7.347612781">
<ele>119.600</ele>
<time>2024-04-19T15:43:27Z</time>
<speed>7.007000</speed>
</trkpt>
<trkpt lat="51.447855290" lon="7.347641196">
<ele>119.400</ele>
<time>2024-04-19T15:43:28Z</time>
<speed>7.007000</speed>
</trkpt>
<trkpt lat="51.447984707" lon="7.347690482">
<ele>118.200</ele>
<time>2024-04-19T15:43:30Z</time>
<speed>7.091000</speed>
</trkpt>
<trkpt lat="51.448172964" lon="7.347761476">
<ele>117.400</ele>
<time>2024-04-19T15:43:33Z</time>
<speed>7.147000</speed>
</trkpt>
<trkpt lat="51.448236583" lon="7.347787460">
<ele>117.400</ele>
<time>2024-04-19T15:43:34Z</time>
<speed>7.147000</speed>
</trkpt>
<trkpt lat="51.448294669" lon="7.347812522">
<ele>117.200</ele>
<time>2024-04-19T15:43:35Z</time>
<speed>7.091000</speed>
</trkpt>
<trkpt lat="51.448354349" lon="7.347840769">
<ele>116.800</ele>
<time>2024-04-19T15:43:36Z</time>
<speed>7.091000</speed>
</trkpt>
<trkpt lat="51.448413692" lon="7.347869435">
<ele>116.800</ele>
<time>2024-04-19T15:43:37Z</time>
<speed>7.091000</speed>
</trkpt>
<trkpt lat="51.448523412" lon="7.347918637">
<ele>116.400</ele>
<time>2024-04-19T15:43:39Z</time>
<speed>6.802000</speed>
</trkpt>
<trkpt lat="51.448576888" lon="7.347932467">
<ele>116.200</ele>
<time>2024-04-19T15:43:40Z</time>
<speed>6.606000</speed>
</trkpt>
<trkpt lat="51.448686188" lon="7.347959206">
<ele>116.200</ele>
<time>2024-04-19T15:43:42Z</time>
<speed>6.578000</speed>
</trkpt>
<trkpt lat="51.448785346" lon="7.347957864">
<ele>115.800</ele>
<time>2024-04-19T15:43:44Z</time>
<speed>5.953000</speed>
</trkpt>
<trkpt lat="51.448837062" lon="7.347960630">
<ele>115.800</ele>
<time>2024-04-19T15:43:45Z</time>
<speed>6.364000</speed>
</trkpt>
<trkpt lat="51.448889198" lon="7.347965743">
<ele>115.800</ele>
<time>2024-04-19T15:43:46Z</time>
<speed>5.309000</speed>
</trkpt>
<trkpt lat="51.448993804" lon="7.347982340">
<ele>115.600</ele>
<time>2024-04-19T15:43:48Z</time>
<speed>6.205000</speed>
</trkpt>
<trkpt lat="51.449108636" lon="7.347994242">
<ele>115.400</ele>
<time>2024-04-19T15:43:50Z</time>
<speed>6.205000</speed>
</trkpt>
<trkpt lat="51.449168567" lon="7.347977897">
<ele>115.000</ele>
<time>2024-04-19T15:43:51Z</time>
<speed>6.205000</speed>
</trkpt>
<trkpt lat="51.449290775" lon="7.347995667">
<ele>114.800</ele>
<time>2024-04-19T15:43:53Z</time>
<speed>6.895000</speed>
</trkpt>
<trkpt lat="51.449661758" lon="7.347987955">
<ele>114.000</ele>
<time>2024-04-19T15:43:59Z</time>
<speed>7.269000</speed>
</trkpt>
<trkpt lat="51.449722443" lon="7.347977562">
<ele>114.000</ele>
<time>2024-04-19T15:44:00Z</time>
<speed>7.259000</speed>
</trkpt>
<trkpt lat="51.449976750" lon="7.347970689">
<ele>113.600</ele>
<time>2024-04-19T15:44:04Z</time>
<speed>6.998000</speed>
</trkpt>
<trkpt lat="51.450036429" lon="7.347979490">
<ele>113.600</ele>
<time>2024-04-19T15:44:05Z</time>
<speed>6.998000</speed>
</trkpt>
<trkpt lat="51.450100299" lon="7.348000277">
<ele>113.200</ele>
<time>2024-04-19T15:44:06Z</time>
<speed>7.045000</speed>
</trkpt>
<trkpt lat="51.450165091" lon="7.348030703">
<ele>113.000</ele>
<time>2024-04-19T15:44:07Z</time>
<speed>7.073000</speed>
</trkpt>
<trkpt lat="51.450277828" lon="7.348114522">
<ele>112.800</ele>
<time>2024-04-19T15:44:09Z</time>
<speed>7.026000</speed>
</trkpt>
<trkpt lat="51.450757189" lon="7.348583741">
<ele>112.200</ele>
<time>2024-04-19T15:44:17Z</time>
<speed>7.455000</speed>
</trkpt>
<trkpt lat="51.451035803" lon="7.348986492">
<ele>112.200</ele>
<time>2024-04-19T15:44:23Z</time>
<speed>6.522000</speed>
</trkpt>
<trkpt lat="51.451380635" lon="7.349499129">
<ele>112.400</ele>
<time>2024-04-19T15:44:31Z</time>
<speed>6.522000</speed>
</trkpt>
<trkpt lat="51.451469064" lon="7.349619996">
<ele>112.400</ele>
<time>2024-04-19T15:44:33Z</time>
<speed>6.513000</speed>
</trkpt>
<trkpt lat="51.451668302" lon="7.349814037">
<ele>112.600</ele>
<time>2024-04-19T15:44:37Z</time>
<speed>6.298000</speed>
</trkpt>
<trkpt lat="51.451745080" lon="7.349966923">
<ele>112.600</ele>
<time>2024-04-19T15:44:39Z</time>
<speed>6.336000</speed>
</trkpt>
<trkpt lat="51.451745918" lon="7.350058872">
<ele>112.800</ele>
<time>2024-04-19T15:44:40Z</time>
<speed>6.298000</speed>
</trkpt>
<trkpt lat="51.451730747" lon="7.350147720">
<ele>113.000</ele>
<time>2024-04-19T15:44:41Z</time>
<speed>6.298000</speed>
</trkpt>
<trkpt lat="51.451712642" lon="7.350233803">
<ele>113.000</ele>
<time>2024-04-19T15:44:42Z</time>
<speed>6.298000</speed>
</trkpt>
<trkpt lat="51.451686155" lon="7.350316783">
<ele>113.200</ele>
<time>2024-04-19T15:44:43Z</time>
<speed>6.336000</speed>
</trkpt>
<trkpt lat="51.451480296" lon="7.350989264">
<ele>113.400</ele>
<time>2024-04-19T15:44:51Z</time>
<speed>6.503000</speed>
</trkpt>
<trkpt lat="51.451444086" lon="7.351249270">
<ele>113.600</ele>
<time>2024-04-19T15:44:54Z</time>
<speed>6.476000</speed>
</trkpt>
<trkpt lat="51.451412989" lon="7.351621427">
<ele>114.000</ele>
<time>2024-04-19T15:44:58Z</time>
<speed>6.476000</speed>
</trkpt>
<trkpt lat="51.451412318" lon="7.351719076">
<ele>114.400</ele>
<time>2024-04-19T15:44:59Z</time>
<speed>6.476000</speed>
</trkpt>
<trkpt lat="51.451411480" lon="7.351908423">
<ele>115.000</ele>
<time>2024-04-19T15:45:01Z</time>
<speed>6.550000</speed>
</trkpt>
<trkpt lat="51.451413073" lon="7.352002552">
<ele>115.200</ele>
<time>2024-04-19T15:45:02Z</time>
<speed>6.550000</speed>
</trkpt>
<trkpt lat="51.451430926" lon="7.352177734">
<ele>116.400</ele>
<time>2024-04-19T15:45:04Z</time>
<speed>6.550000</speed>
</trkpt>
<trkpt lat="51.451456910" lon="7.352333469">
<ele>117.200</ele>
<time>2024-04-19T15:45:06Z</time>
<speed>5.682000</speed>
</trkpt>
<trkpt lat="51.451469567" lon="7.352408823">
<ele>117.400</ele>
<time>2024-04-19T15:45:07Z</time>
<speed>5.682000</speed>
</trkpt>
<trkpt lat="51.451505357" lon="7.352556344">
<ele>117.800</ele>
<time>2024-04-19T15:45:09Z</time>
<speed>5.944000</speed>
</trkpt>
<trkpt lat="51.451539639" lon="7.352688359">
<ele>118.400</ele>
<time>2024-04-19T15:45:11Z</time>
<speed>4.824000</speed>
</trkpt>
<trkpt lat="51.451556822" lon="7.352749044">
<ele>118.600</ele>
<time>2024-04-19T15:45:12Z</time>
<speed>4.787000</speed>
</trkpt>
<trkpt lat="51.451629326" lon="7.352948785">
<ele>119.000</ele>
<time>2024-04-19T15:45:16Z</time>
<speed>3.387000</speed>
</trkpt>
<trkpt lat="51.451659668" lon="7.352995472">
<ele>119.800</ele>
<time>2024-04-19T15:45:18Z</time>
<speed>2.043000</speed>
</trkpt>
<trkpt lat="51.451670984" lon="7.353007039">
<ele>120.000</ele>
<time>2024-04-19T15:45:21Z</time>
<speed>0.000000</speed>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="51.451735022" lon="7.353031011">
<ele>120.400</ele>
<time>2024-04-19T15:45:33Z</time>
<speed>1.717000</speed>
</trkpt>
<trkpt lat="51.451752204" lon="7.353037801">
<ele>120.800</ele>
<time>2024-04-19T15:45:34Z</time>
<speed>1.717000</speed>
</trkpt>
<trkpt lat="51.451795287" lon="7.353065712">
<ele>121.000</ele>
<time>2024-04-19T15:45:36Z</time>
<speed>2.090000</speed>
</trkpt>
<trkpt lat="51.451829067" lon="7.353099659">
<ele>121.000</ele>
<time>2024-04-19T15:45:39Z</time>
<speed>1.698000</speed>
</trkpt>
<trkpt lat="51.451839125" lon="7.353107035">
<ele>121.600</ele>
<time>2024-04-19T15:45:42Z</time>
<speed>0.000000</speed>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="51.451858822" lon="7.353145927">
<ele>121.600</ele>
<time>2024-04-19T15:45:44Z</time>
<speed>1.661000</speed>
</trkpt>
<trkpt lat="51.451868126" lon="7.353162607">
<ele>121.400</ele>
<time>2024-04-19T15:45:45Z</time>
<speed>1.642000</speed>
</trkpt>
</trkseg>
</trk>
</gpx>

View File

@ -0,0 +1,746 @@
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
<time>2024-07-21T12:06:43.732Z</time>
<bounds minlat="51.437097620" minlon="7.335111843" maxlat="51.448127115" maxlon="7.347458638"/>
<wpt lat="51.437175153" lon="7.335113939">
<name>LAP001</name>
<cmt>LAP001</cmt>
<desc>LAP001</desc>
</wpt>
<trk>
<trkseg>
<trkpt lat="51.448127115" lon="7.347455788">
<ele>108.400</ele>
<time>2024-06-18T12:18:21Z</time>
<speed>6.578000</speed>
</trkpt>
<trkpt lat="51.448109429" lon="7.347385883">
<ele>108.400</ele>
<time>2024-06-18T12:18:22Z</time>
<speed>6.578000</speed>
</trkpt>
<trkpt lat="51.447986048" lon="7.347458638">
<ele>108.000</ele>
<time>2024-06-18T12:18:24Z</time>
<speed>6.578000</speed>
</trkpt>
<trkpt lat="51.447657980" lon="7.347361911">
<ele>109.200</ele>
<time>2024-06-18T12:18:29Z</time>
<speed>6.485000</speed>
</trkpt>
<trkpt lat="51.447604420" lon="7.347329976">
<ele>109.400</ele>
<time>2024-06-18T12:18:30Z</time>
<speed>6.485000</speed>
</trkpt>
<trkpt lat="51.447433010" lon="7.347254120">
<ele>110.200</ele>
<time>2024-06-18T12:18:33Z</time>
<speed>6.401000</speed>
</trkpt>
<trkpt lat="51.447330164" lon="7.347221095">
<ele>110.400</ele>
<time>2024-06-18T12:18:35Z</time>
<speed>6.392000</speed>
</trkpt>
<trkpt lat="51.447274592" lon="7.347200727">
<ele>110.600</ele>
<time>2024-06-18T12:18:36Z</time>
<speed>6.392000</speed>
</trkpt>
<trkpt lat="51.447210470" lon="7.347167870">
<ele>110.600</ele>
<time>2024-06-18T12:18:37Z</time>
<speed>6.354000</speed>
</trkpt>
<trkpt lat="51.446996732" lon="7.347072316">
<ele>111.200</ele>
<time>2024-06-18T12:18:41Z</time>
<speed>6.354000</speed>
</trkpt>
<trkpt lat="51.446884749" lon="7.347024875">
<ele>111.400</ele>
<time>2024-06-18T12:18:43Z</time>
<speed>6.354000</speed>
</trkpt>
<trkpt lat="51.446726751" lon="7.346923621">
<ele>111.800</ele>
<time>2024-06-18T12:18:46Z</time>
<speed>6.354000</speed>
</trkpt>
<trkpt lat="51.446629856" lon="7.346828571">
<ele>111.800</ele>
<time>2024-06-18T12:18:48Z</time>
<speed>6.317000</speed>
</trkpt>
<trkpt lat="51.446581241" lon="7.346794121">
<ele>112.000</ele>
<time>2024-06-18T12:18:49Z</time>
<speed>6.261000</speed>
</trkpt>
<trkpt lat="51.446477473" lon="7.346730251">
<ele>112.200</ele>
<time>2024-06-18T12:18:51Z</time>
<speed>6.261000</speed>
</trkpt>
<trkpt lat="51.446322072" lon="7.346610306">
<ele>112.400</ele>
<time>2024-06-18T12:18:54Z</time>
<speed>6.140000</speed>
</trkpt>
<trkpt lat="51.446283180" lon="7.346579712">
<ele>112.600</ele>
<time>2024-06-18T12:18:55Z</time>
<speed>6.140000</speed>
</trkpt>
<trkpt lat="51.446146974" lon="7.346425485">
<ele>112.600</ele>
<time>2024-06-18T12:18:58Z</time>
<speed>6.140000</speed>
</trkpt>
<trkpt lat="51.445943797" lon="7.346080737">
<ele>113.000</ele>
<time>2024-06-18T12:19:03Z</time>
<speed>6.186000</speed>
</trkpt>
<trkpt lat="51.445873557" lon="7.345953081">
<ele>113.200</ele>
<time>2024-06-18T12:19:05Z</time>
<speed>6.252000</speed>
</trkpt>
<trkpt lat="51.445753025" lon="7.345751412">
<ele>113.600</ele>
<time>2024-06-18T12:19:08Z</time>
<speed>6.336000</speed>
</trkpt>
<trkpt lat="51.445630817" lon="7.345540859">
<ele>113.800</ele>
<time>2024-06-18T12:19:11Z</time>
<speed>6.410000</speed>
</trkpt>
<trkpt lat="51.445476254" lon="7.345259478">
<ele>114.600</ele>
<time>2024-06-18T12:19:15Z</time>
<speed>6.476000</speed>
</trkpt>
<trkpt lat="51.445440883" lon="7.345182532">
<ele>114.600</ele>
<time>2024-06-18T12:19:16Z</time>
<speed>6.522000</speed>
</trkpt>
<trkpt lat="51.445404841" lon="7.345108520">
<ele>114.800</ele>
<time>2024-06-18T12:19:17Z</time>
<speed>6.522000</speed>
</trkpt>
<trkpt lat="51.445183558" lon="7.344674841">
<ele>115.200</ele>
<time>2024-06-18T12:19:23Z</time>
<speed>6.466000</speed>
</trkpt>
<trkpt lat="51.445107283" lon="7.344542239">
<ele>115.400</ele>
<time>2024-06-18T12:19:25Z</time>
<speed>6.457000</speed>
</trkpt>
<trkpt lat="51.444991278" lon="7.344359597">
<ele>115.200</ele>
<time>2024-06-18T12:19:28Z</time>
<speed>6.354000</speed>
</trkpt>
<trkpt lat="51.444951715" lon="7.344298577">
<ele>115.200</ele>
<time>2024-06-18T12:19:29Z</time>
<speed>6.289000</speed>
</trkpt>
<trkpt lat="51.444876529" lon="7.344177458">
<ele>115.200</ele>
<time>2024-06-18T12:19:31Z</time>
<speed>6.102000</speed>
</trkpt>
<trkpt lat="51.444851970" lon="7.344103949">
<ele>115.200</ele>
<time>2024-06-18T12:19:32Z</time>
<speed>6.084000</speed>
</trkpt>
<trkpt lat="51.444832692" lon="7.344025075">
<ele>115.800</ele>
<time>2024-06-18T12:19:33Z</time>
<speed>6.084000</speed>
</trkpt>
<trkpt lat="51.444796231" lon="7.343879230">
<ele>116.200</ele>
<time>2024-06-18T12:19:35Z</time>
<speed>5.981000</speed>
</trkpt>
<trkpt lat="51.444781730" lon="7.343726093">
<ele>116.600</ele>
<time>2024-06-18T12:19:37Z</time>
<speed>5.860000</speed>
</trkpt>
<trkpt lat="51.444738731" lon="7.343591396">
<ele>116.800</ele>
<time>2024-06-18T12:19:39Z</time>
<speed>5.645000</speed>
</trkpt>
<trkpt lat="51.444667485" lon="7.343473881">
<ele>116.600</ele>
<time>2024-06-18T12:19:41Z</time>
<speed>5.645000</speed>
</trkpt>
<trkpt lat="51.444626581" lon="7.343412191">
<ele>116.600</ele>
<time>2024-06-18T12:19:42Z</time>
<speed>5.645000</speed>
</trkpt>
<trkpt lat="51.444539828" lon="7.343180431">
<ele>116.400</ele>
<time>2024-06-18T12:19:45Z</time>
<speed>5.748000</speed>
</trkpt>
<trkpt lat="51.444343356" lon="7.342730155">
<ele>116.400</ele>
<time>2024-06-18T12:19:51Z</time>
<speed>6.289000</speed>
</trkpt>
<trkpt lat="51.444226680" lon="7.342531253">
<ele>117.200</ele>
<time>2024-06-18T12:19:54Z</time>
<speed>6.326000</speed>
</trkpt>
<trkpt lat="51.444100449" lon="7.342349784">
<ele>117.800</ele>
<time>2024-06-18T12:19:57Z</time>
<speed>6.326000</speed>
</trkpt>
<trkpt lat="51.444009757" lon="7.342238976">
<ele>117.800</ele>
<time>2024-06-18T12:19:59Z</time>
<speed>6.326000</speed>
</trkpt>
<trkpt lat="51.443723682" lon="7.341940077">
<ele>117.400</ele>
<time>2024-06-18T12:20:05Z</time>
<speed>6.354000</speed>
</trkpt>
<trkpt lat="51.443633912" lon="7.341839662">
<ele>117.600</ele>
<time>2024-06-18T12:20:07Z</time>
<speed>6.354000</speed>
</trkpt>
<trkpt lat="51.443579597" lon="7.341692392">
<ele>117.600</ele>
<time>2024-06-18T12:20:09Z</time>
<speed>6.224000</speed>
</trkpt>
<trkpt lat="51.443536934" lon="7.341544535">
<ele>117.600</ele>
<time>2024-06-18T12:20:11Z</time>
<speed>6.121000</speed>
</trkpt>
<trkpt lat="51.443462335" lon="7.341446299">
<ele>117.600</ele>
<time>2024-06-18T12:20:13Z</time>
<speed>5.860000</speed>
</trkpt>
<trkpt lat="51.443378432" lon="7.341447975">
<ele>118.200</ele>
<time>2024-06-18T12:20:15Z</time>
<speed>4.749000</speed>
</trkpt>
<trkpt lat="51.443338702" lon="7.341480162">
<ele>118.400</ele>
<time>2024-06-18T12:20:16Z</time>
<speed>4.749000</speed>
</trkpt>
<trkpt lat="51.443289667" lon="7.341503548">
<ele>118.400</ele>
<time>2024-06-18T12:20:17Z</time>
<speed>5.291000</speed>
</trkpt>
<trkpt lat="51.443188665" lon="7.341495920">
<ele>118.800</ele>
<time>2024-06-18T12:20:19Z</time>
<speed>5.468000</speed>
</trkpt>
<trkpt lat="51.443010047" lon="7.341377567">
<ele>119.200</ele>
<time>2024-06-18T12:20:23Z</time>
<speed>5.374000</speed>
</trkpt>
<trkpt lat="51.442966796" lon="7.341349488">
<ele>119.200</ele>
<time>2024-06-18T12:20:24Z</time>
<speed>5.365000</speed>
</trkpt>
<trkpt lat="51.442615259" lon="7.341144718">
<ele>120.000</ele>
<time>2024-06-18T12:20:31Z</time>
<speed>6.811000</speed>
</trkpt>
<trkpt lat="51.442553233" lon="7.341088224">
<ele>120.400</ele>
<time>2024-06-18T12:20:32Z</time>
<speed>7.735000</speed>
</trkpt>
<trkpt lat="51.442433205" lon="7.340950258">
<ele>121.000</ele>
<time>2024-06-18T12:20:34Z</time>
<speed>8.127000</speed>
</trkpt>
<trkpt lat="51.442377632" lon="7.340878425">
<ele>121.000</ele>
<time>2024-06-18T12:20:35Z</time>
<speed>7.866000</speed>
</trkpt>
<trkpt lat="51.442153500" lon="7.340646246">
<ele>120.800</ele>
<time>2024-06-18T12:20:39Z</time>
<speed>7.539000</speed>
</trkpt>
<trkpt lat="51.442089127" lon="7.340605343">
<ele>120.600</ele>
<time>2024-06-18T12:20:40Z</time>
<speed>7.539000</speed>
</trkpt>
<trkpt lat="51.441777572" lon="7.340425132">
<ele>120.200</ele>
<time>2024-06-18T12:20:45Z</time>
<speed>7.437000</speed>
</trkpt>
<trkpt lat="51.441532066" lon="7.340305941">
<ele>119.800</ele>
<time>2024-06-18T12:20:49Z</time>
<speed>7.269000</speed>
</trkpt>
<trkpt lat="51.441342216" lon="7.340265457">
<ele>119.600</ele>
<time>2024-06-18T12:20:52Z</time>
<speed>7.101000</speed>
</trkpt>
<trkpt lat="51.441276167" lon="7.340258583">
<ele>119.400</ele>
<time>2024-06-18T12:20:53Z</time>
<speed>6.998000</speed>
</trkpt>
<trkpt lat="51.441211374" lon="7.340251710">
<ele>119.400</ele>
<time>2024-06-18T12:20:54Z</time>
<speed>6.998000</speed>
</trkpt>
<trkpt lat="51.440850198" lon="7.340168562">
<ele>119.200</ele>
<time>2024-06-18T12:21:00Z</time>
<speed>6.793000</speed>
</trkpt>
<trkpt lat="51.440729918" lon="7.340142578">
<ele>119.000</ele>
<time>2024-06-18T12:21:02Z</time>
<speed>6.755000</speed>
</trkpt>
<trkpt lat="51.440666718" lon="7.340133106">
<ele>118.600</ele>
<time>2024-06-18T12:21:03Z</time>
<speed>6.737000</speed>
</trkpt>
<trkpt lat="51.440497236" lon="7.340070661">
<ele>118.400</ele>
<time>2024-06-18T12:21:06Z</time>
<speed>6.494000</speed>
</trkpt>
<trkpt lat="51.440396905" lon="7.340004947">
<ele>118.200</ele>
<time>2024-06-18T12:21:08Z</time>
<speed>5.953000</speed>
</trkpt>
<trkpt lat="51.440345440" lon="7.339946944">
<ele>118.400</ele>
<time>2024-06-18T12:21:09Z</time>
<speed>6.280000</speed>
</trkpt>
<trkpt lat="51.440302106" lon="7.339882068">
<ele>118.400</ele>
<time>2024-06-18T12:21:10Z</time>
<speed>6.438000</speed>
</trkpt>
<trkpt lat="51.440263297" lon="7.339808978">
<ele>118.400</ele>
<time>2024-06-18T12:21:11Z</time>
<speed>6.438000</speed>
</trkpt>
<trkpt lat="51.440222394" lon="7.339733373">
<ele>118.200</ele>
<time>2024-06-18T12:21:12Z</time>
<speed>6.438000</speed>
</trkpt>
<trkpt lat="51.440168079" lon="7.339442940">
<ele>117.800</ele>
<time>2024-06-18T12:21:15Z</time>
<speed>6.559000</speed>
</trkpt>
<trkpt lat="51.440159027" lon="7.339337915">
<ele>117.800</ele>
<time>2024-06-18T12:21:16Z</time>
<speed>6.578000</speed>
</trkpt>
<trkpt lat="51.440159362" lon="7.339144126">
<ele>117.800</ele>
<time>2024-06-18T12:21:18Z</time>
<speed>6.578000</speed>
</trkpt>
<trkpt lat="51.440108484" lon="7.339014960">
<ele>117.800</ele>
<time>2024-06-18T12:21:20Z</time>
<speed>6.559000</speed>
</trkpt>
<trkpt lat="51.440047044" lon="7.338990150">
<ele>117.800</ele>
<time>2024-06-18T12:21:21Z</time>
<speed>6.559000</speed>
</trkpt>
<trkpt lat="51.439920478" lon="7.338969028">
<ele>117.800</ele>
<time>2024-06-18T12:21:23Z</time>
<speed>6.448000</speed>
</trkpt>
<trkpt lat="51.439757450" lon="7.338956539">
<ele>118.600</ele>
<time>2024-06-18T12:21:26Z</time>
<speed>6.018000</speed>
</trkpt>
<trkpt lat="51.439702380" lon="7.338959388">
<ele>119.200</ele>
<time>2024-06-18T12:21:27Z</time>
<speed>6.018000</speed>
</trkpt>
<trkpt lat="51.439649994" lon="7.338957042">
<ele>119.600</ele>
<time>2024-06-18T12:21:28Z</time>
<speed>5.990000</speed>
</trkpt>
<trkpt lat="51.439597020" lon="7.338950252">
<ele>119.800</ele>
<time>2024-06-18T12:21:29Z</time>
<speed>5.832000</speed>
</trkpt>
<trkpt lat="51.439500293" lon="7.338939440">
<ele>120.200</ele>
<time>2024-06-18T12:21:31Z</time>
<speed>5.057000</speed>
</trkpt>
<trkpt lat="51.439456204" lon="7.338933069">
<ele>120.200</ele>
<time>2024-06-18T12:21:32Z</time>
<speed>5.580000</speed>
</trkpt>
<trkpt lat="51.439286554" lon="7.338897865">
<ele>119.600</ele>
<time>2024-06-18T12:21:35Z</time>
<speed>6.149000</speed>
</trkpt>
<trkpt lat="51.439167196" lon="7.338924687">
<ele>119.200</ele>
<time>2024-06-18T12:21:37Z</time>
<speed>6.513000</speed>
</trkpt>
<trkpt lat="51.439108187" lon="7.338960562">
<ele>119.000</ele>
<time>2024-06-18T12:21:38Z</time>
<speed>6.541000</speed>
</trkpt>
<trkpt lat="51.439052280" lon="7.339010183">
<ele>118.400</ele>
<time>2024-06-18T12:21:39Z</time>
<speed>6.149000</speed>
</trkpt>
<trkpt lat="51.438946584" lon="7.339069275">
<ele>118.000</ele>
<time>2024-06-18T12:21:41Z</time>
<speed>6.448000</speed>
</trkpt>
<trkpt lat="51.438876092" lon="7.339074807">
<ele>117.800</ele>
<time>2024-06-18T12:21:42Z</time>
<speed>6.867000</speed>
</trkpt>
<trkpt lat="51.438732175" lon="7.339089392">
<ele>117.200</ele>
<time>2024-06-18T12:21:44Z</time>
<speed>7.931000</speed>
</trkpt>
<trkpt lat="51.438592449" lon="7.339064498">
<ele>115.800</ele>
<time>2024-06-18T12:21:46Z</time>
<speed>8.006000</speed>
</trkpt>
<trkpt lat="51.438534530" lon="7.339052092">
<ele>114.800</ele>
<time>2024-06-18T12:21:47Z</time>
<speed>6.709000</speed>
</trkpt>
<trkpt lat="51.438489519" lon="7.339043459">
<ele>114.400</ele>
<time>2024-06-18T12:21:48Z</time>
<speed>5.962000</speed>
</trkpt>
<trkpt lat="51.438453645" lon="7.339024013">
<ele>113.800</ele>
<time>2024-06-18T12:21:49Z</time>
<speed>4.647000</speed>
</trkpt>
<trkpt lat="51.438391451" lon="7.339007836">
<ele>113.000</ele>
<time>2024-06-18T12:21:51Z</time>
<speed>3.630000</speed>
</trkpt>
<trkpt lat="51.438318780" lon="7.339081932">
<ele>112.400</ele>
<time>2024-06-18T12:21:53Z</time>
<speed>5.188000</speed>
</trkpt>
<trkpt lat="51.438300340" lon="7.339132978">
<ele>112.400</ele>
<time>2024-06-18T12:21:54Z</time>
<speed>4.283000</speed>
</trkpt>
<trkpt lat="51.438231524" lon="7.339288378">
<ele>112.600</ele>
<time>2024-06-18T12:21:58Z</time>
<speed>3.807000</speed>
</trkpt>
<trkpt lat="51.438090960" lon="7.339288546">
<ele>111.600</ele>
<time>2024-06-18T12:22:02Z</time>
<speed>5.029000</speed>
</trkpt>
<trkpt lat="51.437921980" lon="7.339256527">
<ele>110.800</ele>
<time>2024-06-18T12:22:05Z</time>
<speed>6.326000</speed>
</trkpt>
<trkpt lat="51.437850147" lon="7.339260466">
<ele>110.200</ele>
<time>2024-06-18T12:22:06Z</time>
<speed>7.567000</speed>
</trkpt>
<trkpt lat="51.437775549" lon="7.339250827">
<ele>109.800</ele>
<time>2024-06-18T12:22:07Z</time>
<speed>7.931000</speed>
</trkpt>
<trkpt lat="51.437646803" lon="7.339137252">
<ele>109.600</ele>
<time>2024-06-18T12:22:09Z</time>
<speed>8.099000</speed>
</trkpt>
<trkpt lat="51.437612101" lon="7.339027282">
<ele>108.400</ele>
<time>2024-06-18T12:22:10Z</time>
<speed>8.043000</speed>
</trkpt>
<trkpt lat="51.437600199" lon="7.338903314">
<ele>108.000</ele>
<time>2024-06-18T12:22:11Z</time>
<speed>7.931000</speed>
</trkpt>
<trkpt lat="51.437559379" lon="7.338304762">
<ele>107.600</ele>
<time>2024-06-18T12:22:16Z</time>
<speed>8.099000</speed>
</trkpt>
<trkpt lat="51.437537000" lon="7.338198144">
<ele>107.200</ele>
<time>2024-06-18T12:22:17Z</time>
<speed>8.099000</speed>
</trkpt>
<trkpt lat="51.437521745" lon="7.338094208">
<ele>106.400</ele>
<time>2024-06-18T12:22:18Z</time>
<speed>8.099000</speed>
</trkpt>
<trkpt lat="51.437507831" lon="7.337988429">
<ele>106.200</ele>
<time>2024-06-18T12:22:19Z</time>
<speed>8.071000</speed>
</trkpt>
<trkpt lat="51.437490983" lon="7.337894384">
<ele>105.600</ele>
<time>2024-06-18T12:22:20Z</time>
<speed>7.521000</speed>
</trkpt>
<trkpt lat="51.437480338" lon="7.337810397">
<ele>105.400</ele>
<time>2024-06-18T12:22:21Z</time>
<speed>6.476000</speed>
</trkpt>
<trkpt lat="51.437474135" lon="7.337661954">
<ele>105.000</ele>
<time>2024-06-18T12:22:23Z</time>
<speed>5.384000</speed>
</trkpt>
<trkpt lat="51.437453935" lon="7.337525580">
<ele>104.200</ele>
<time>2024-06-18T12:22:26Z</time>
<speed>2.631000</speed>
</trkpt>
<trkpt lat="51.437460054" lon="7.337428685">
<ele>104.000</ele>
<time>2024-06-18T12:22:29Z</time>
<speed>2.165000</speed>
</trkpt>
<trkpt lat="51.437462736" lon="7.337391470">
<ele>103.800</ele>
<time>2024-06-18T12:22:31Z</time>
<speed>1.316000</speed>
</trkpt>
<trkpt lat="51.437468771" lon="7.337322151">
<ele>103.800</ele>
<time>2024-06-18T12:22:34Z</time>
<speed>1.306000</speed>
</trkpt>
<trkpt lat="51.437482769" lon="7.337263729">
<ele>103.600</ele>
<time>2024-06-18T12:22:36Z</time>
<speed>1.316000</speed>
</trkpt>
<trkpt lat="51.437473800" lon="7.337268926">
<ele>103.600</ele>
<time>2024-06-18T12:22:37Z</time>
<speed>1.306000</speed>
</trkpt>
<trkpt lat="51.437449073" lon="7.337277140">
<ele>103.400</ele>
<time>2024-06-18T12:22:39Z</time>
<speed>1.316000</speed>
</trkpt>
<trkpt lat="51.437492743" lon="7.337088799">
<ele>103.200</ele>
<time>2024-06-18T12:22:42Z</time>
<speed>5.160000</speed>
</trkpt>
<trkpt lat="51.437485619" lon="7.336924346">
<ele>103.000</ele>
<time>2024-06-18T12:22:44Z</time>
<speed>5.505000</speed>
</trkpt>
<trkpt lat="51.437445637" lon="7.336752098">
<ele>103.000</ele>
<time>2024-06-18T12:22:46Z</time>
<speed>5.160000</speed>
</trkpt>
<trkpt lat="51.437420072" lon="7.336665764">
<ele>102.800</ele>
<time>2024-06-18T12:22:47Z</time>
<speed>5.169000</speed>
</trkpt>
<trkpt lat="51.437346647" lon="7.336395867">
<ele>102.400</ele>
<time>2024-06-18T12:22:50Z</time>
<speed>6.392000</speed>
</trkpt>
<trkpt lat="51.437330553" lon="7.336300649">
<ele>102.400</ele>
<time>2024-06-18T12:22:51Z</time>
<speed>6.802000</speed>
</trkpt>
<trkpt lat="51.437306497" lon="7.335988339">
<ele>102.200</ele>
<time>2024-06-18T12:22:54Z</time>
<speed>7.483000</speed>
</trkpt>
<trkpt lat="51.437312448" lon="7.335764039">
<ele>101.600</ele>
<time>2024-06-18T12:22:56Z</time>
<speed>7.390000</speed>
</trkpt>
<trkpt lat="51.437282022" lon="7.335542170">
<ele>101.200</ele>
<time>2024-06-18T12:22:58Z</time>
<speed>7.241000</speed>
</trkpt>
<trkpt lat="51.437285207" lon="7.335441671">
<ele>100.000</ele>
<time>2024-06-18T12:22:59Z</time>
<speed>7.241000</speed>
</trkpt>
<trkpt lat="51.437295433" lon="7.335354583">
<ele>98.600</ele>
<time>2024-06-18T12:23:00Z</time>
<speed>6.793000</speed>
</trkpt>
<trkpt lat="51.437313538" lon="7.335266992">
<ele>98.600</ele>
<time>2024-06-18T12:23:02Z</time>
<speed>2.463000</speed>
</trkpt>
<trkpt lat="51.437324770" lon="7.335185604">
<ele>99.000</ele>
<time>2024-06-18T12:23:04Z</time>
<speed>1.708000</speed>
</trkpt>
<trkpt lat="51.437233156" lon="7.335141599">
<ele>99.000</ele>
<time>2024-06-18T12:23:05Z</time>
<speed>2.370000</speed>
</trkpt>
<trkpt lat="51.437113546" lon="7.335127182">
<ele>98.600</ele>
<time>2024-06-18T12:23:08Z</time>
<speed>1.008000</speed>
</trkpt>
<trkpt lat="51.437112289" lon="7.335133385">
<ele>98.400</ele>
<time>2024-06-18T12:23:09Z</time>
<speed>1.008000</speed>
</trkpt>
<trkpt lat="51.437097620" lon="7.335231956">
<ele>98.400</ele>
<time>2024-06-18T12:23:12Z</time>
<speed>1.232000</speed>
</trkpt>
<trkpt lat="51.437102733" lon="7.335230196">
<ele>98.200</ele>
<time>2024-06-18T12:23:15Z</time>
<speed>1.008000</speed>
</trkpt>
<trkpt lat="51.437108433" lon="7.335228436">
<ele>98.200</ele>
<time>2024-06-18T12:23:17Z</time>
<speed>0.998000</speed>
</trkpt>
<trkpt lat="51.437117904" lon="7.335228603">
<ele>98.200</ele>
<time>2024-06-18T12:23:18Z</time>
<speed>1.008000</speed>
</trkpt>
<trkpt lat="51.437122514" lon="7.335224329">
<ele>98.000</ele>
<time>2024-06-18T12:23:19Z</time>
<speed>1.082000</speed>
</trkpt>
<trkpt lat="51.437120084" lon="7.335222485">
<ele>98.000</ele>
<time>2024-06-18T12:23:22Z</time>
<speed>0.000000</speed>
</trkpt>
</trkseg>
<trkseg>
<trkpt lat="51.437143805" lon="7.335128440">
<ele>98.200</ele>
<time>2024-06-18T12:23:39Z</time>
<speed>1.633000</speed>
</trkpt>
<trkpt lat="51.437160233" lon="7.335111843">
<ele>98.200</ele>
<time>2024-06-18T12:23:41Z</time>
<speed>1.260000</speed>
</trkpt>
<trkpt lat="51.437175153" lon="7.335113939">
<ele>98.200</ele>
<time>2024-06-18T12:23:42Z</time>
<speed>1.260000</speed>
</trkpt>
</trkseg>
</trk>
</gpx>

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
Flask==2.2.5
Werkzeug==2.2.3

133
templates/index.html Normal file
View File

@ -0,0 +1,133 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FIT to GPX Converter</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script>
function refreshPage() {
location.reload();
}
setInterval(refreshPage, 30000);
tailwind.config = {
theme: {
extend: {
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
}
},
animation: {
fadeIn: 'fadeIn 0.5s ease-out',
}
}
}
}
</script>
</head>
<body class="bg-gray-100 min-h-screen p-8" x-data="{
selectedInputFiles: [],
selectedOutputFiles: [],
async deleteFiles(folder) {
const files = folder === 'input' ? this.selectedInputFiles : this.selectedOutputFiles;
if (files.length === 0) return;
const response = await fetch('/delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ files, folder }),
});
if (response.ok) {
location.reload();
} else {
alert('Error deleting files');
}
}
}">
<div class="max-w-4xl mx-auto bg-white rounded-lg shadow-xl overflow-hidden animate-fadeIn">
<div class="bg-blue-600 text-white p-6">
<h1 class="text-3xl font-bold mb-2">FIT to GPX Converter</h1>
<p class="text-lg">Convert your .fit files to .gpx format with ease!</p>
</div>
<div class="p-6">
<div class="bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4 mb-6 rounded animate-fadeIn" role="alert">
<h2 class="font-bold text-lg mb-2">Quick Start Guide</h2>
<ol class="list-decimal list-inside space-y-1">
<li>Select a .fit file using the file input below.</li>
<li>Click the "Upload and Convert" button.</li>
<li>Wait for the conversion to complete.</li>
<li>Download your converted .gpx file from the output files list.</li>
</ol>
<p class="mt-2">This tool converts Garmin FIT files to GPX format, allowing you to use your fitness data in a wide range of applications and devices.</p>
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="animate-fadeIn {% if category == 'success' %}bg-green-100 border-green-500 text-green-700{% else %}bg-red-100 border-red-500 text-red-700{% endif %} border-l-4 p-4 mb-4 rounded" role="alert">
<p>{{ message }}</p>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<form method="post" enctype="multipart/form-data" class="mb-6">
<div class="flex flex-col sm:flex-row items-center justify-center space-y-4 sm:space-y-0 sm:space-x-4">
<input type="file" name="file" accept=".fit" class="file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100" required>
<button type="submit" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out transform hover:scale-105">
Upload and Convert
</button>
</div>
</form>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h2 class="text-2xl font-bold mb-4">Input Files:</h2>
{% if input_files %}
<ul class="space-y-2 animate-fadeIn">
{% for file in input_files %}
<li class="flex items-center bg-gray-50 p-3 rounded hover:bg-gray-100 transition duration-300 ease-in-out">
<input type="checkbox" class="mr-2" x-model="selectedInputFiles" :value="'{{ file }}'">
<span class="text-blue-600">{{ file }}</span>
</li>
{% endfor %}
</ul>
<button @click="deleteFiles('input')" class="mt-4 bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out" x-bind:disabled="selectedInputFiles.length === 0">
Delete Selected Input Files
</button>
{% else %}
<p class="text-gray-600">No input files yet. Upload a .fit file to get started!</p>
{% endif %}
</div>
<div>
<h2 class="text-2xl font-bold mb-4">Output Files:</h2>
{% if output_files %}
<ul class="space-y-2 animate-fadeIn">
{% for file in output_files %}
<li class="flex items-center bg-gray-50 p-3 rounded hover:bg-gray-100 transition duration-300 ease-in-out">
<input type="checkbox" class="mr-2" x-model="selectedOutputFiles" :value="'{{ file }}'">
<a href="{{ url_for('download_file', filename=file) }}" class="text-blue-600 hover:text-blue-800">{{ file }}</a>
</li>
{% endfor %}
</ul>
<button @click="deleteFiles('output')" class="mt-4 bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out" x-bind:disabled="selectedOutputFiles.length === 0">
Delete Selected Output Files
</button>
{% else %}
<p class="text-gray-600">No converted files yet. Upload a .fit file to get started!</p>
{% endif %}
</div>
</div>
</div>
</div>
</body>
</html>