From a2bde550cbe6f840e136709d5d07465e637d75e3 Mon Sep 17 00:00:00 2001 From: Vibe Nuage Agent Date: Mon, 18 May 2026 19:22:46 +0000 Subject: [PATCH 1/2] Fix GPX file loading errors in Streamlit app - Changed file opening mode from text ('r') to binary ('rb') in Base.py and main.py to properly parse GPX files which are XML format - Fixed temporary file handling in app.py for both example files and user uploads: - Separated file content reading from temporary file creation - Added explicit mode='wb' for temporary files - Properly closed temporary files before use - Fixed variable shadowing issue where uploaded_file was being overwritten These changes resolve the errors reported in PR #2: - Error when using default GPX example files - Error when uploading GPX files via the upload button The root cause was that gpxpy.parse() requires a file opened in binary mode, not text mode, and the temporary file handling had logic errors. --- src/otGpxTrack/Base.py | 2 +- src/otGpxTrack/main.py | 2 +- streamlitApp/app.py | 20 ++++++++++++-------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/otGpxTrack/Base.py b/src/otGpxTrack/Base.py index 722fdff..467910a 100644 --- a/src/otGpxTrack/Base.py +++ b/src/otGpxTrack/Base.py @@ -60,7 +60,7 @@ def __init__(self, gpx_file_path): def _load_gpx(self): """Load and parse the GPX file.""" - with open(self.gpx_file_path, "r") as f: + with open(self.gpx_file_path, "rb") as f: self.gpx = gpxpy.parse(f) def _extract_points(self): diff --git a/src/otGpxTrack/main.py b/src/otGpxTrack/main.py index 89e7eff..53d6488 100644 --- a/src/otGpxTrack/main.py +++ b/src/otGpxTrack/main.py @@ -25,7 +25,7 @@ def __init__(self, gpx_file_path): def _load_gpx(self): """Load and parse the GPX file.""" - with open(self.gpx_file_path, "r") as f: + with open(self.gpx_file_path, "rb") as f: self.gpx = gpxpy.parse(f) def _extract_points(self): diff --git a/streamlitApp/app.py b/streamlitApp/app.py index fb1c353..15f0f03 100644 --- a/streamlitApp/app.py +++ b/streamlitApp/app.py @@ -89,13 +89,15 @@ def main(): with cols[i]: if (example_dir / example_file).exists(): if st.button(f"Load {example_file}", use_container_width=True): + # Create a temporary file with the example content with open(example_dir / example_file, "rb") as f: - uploaded_file = f.read() - uploaded_file = tempfile.NamedTemporaryFile( - delete=False, suffix=".gpx" - ) - uploaded_file.write(uploaded_file) - uploaded_file.seek(0) + file_content = f.read() + temp_file = tempfile.NamedTemporaryFile( + delete=False, suffix=".gpx", mode='wb' + ) + temp_file.write(file_content) + temp_file.close() + uploaded_file = temp_file if uploaded_file is not None: # Process the uploaded file @@ -103,14 +105,16 @@ def main(): with st.spinner("Processing GPX file..."): # Save to temp file if hasattr(uploaded_file, "name"): + # This is a temp file from example loading temp_file_path = uploaded_file.name else: + # This is a Streamlit UploadedFile temp_file = tempfile.NamedTemporaryFile( - delete=False, suffix=".gpx" + delete=False, suffix=".gpx", mode='wb' ) temp_file.write(uploaded_file.getvalue()) - temp_file_path = temp_file.name temp_file.close() + temp_file_path = temp_file.name # Load the track track = GpxTrack(temp_file_path) From 55ee01056184292a6f67e183653b61011d250579 Mon Sep 17 00:00:00 2001 From: Vibe Nuage Agent Date: Mon, 18 May 2026 19:41:07 +0000 Subject: [PATCH 2/2] Fix quantile extraction in simulate_ar1_speeds - Fixed bug where computeQuantilePerComponent returns a Sample, and [0] returns a Point - Need to use [0][0] to extract the float value from the Point - This was causing TypeError when comparing lower <= mean_speed <= upper --- src/otGpxTrack/Base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/otGpxTrack/Base.py b/src/otGpxTrack/Base.py index 467910a..45170d7 100644 --- a/src/otGpxTrack/Base.py +++ b/src/otGpxTrack/Base.py @@ -378,8 +378,8 @@ def simulate_ar1_speeds(self, segment_indices, sigma_tot=2.5, phi=0.9, n_sims=10 # Calculate statistics using OpenTURNS mean_speed = v_simulees.computeMean()[0] - lower = ot.Sample.computeQuantilePerComponent(v_simulees, 0.025)[0] - upper = ot.Sample.computeQuantilePerComponent(v_simulees, 0.975)[0] + lower = ot.Sample.computeQuantilePerComponent(v_simulees, 0.025)[0][0] + upper = ot.Sample.computeQuantilePerComponent(v_simulees, 0.975)[0][0] return mean_speed, lower, upper, v_simulees