#!/usr/bin/env python3 """ Test script for progressive 3D animation with debugging """ import os import sys sys.path.append('/home/pi/Desktop/traccar_animation') def test_progressive_animation_debug(): """Test the progressive animation with a simple GPS dataset""" print("Testing progressive 3D animation with debug output...") # Find a project with GPS data projects_folder = "/home/pi/Desktop/traccar_animation/resources/projects" if not os.path.exists(projects_folder): print("❌ Projects folder not found!") return # Look for projects projects = [d for d in os.listdir(projects_folder) if os.path.isdir(os.path.join(projects_folder, d))] if not projects: print("❌ No projects found!") return # Use the first project found project_name = projects[0] project_folder = os.path.join(projects_folder, project_name) positions_file = os.path.join(project_folder, "positions.json") if not os.path.exists(positions_file): print(f"❌ No positions.json found in project {project_name}") return print(f"✅ Testing with project: {project_name}") try: # Import the animation generation code import json import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np import cv2 from datetime import datetime # Load GPS data with open(positions_file, 'r') as f: positions = json.load(f) print(f"✅ Loaded {len(positions)} GPS points") if len(positions) < 2: print("❌ Need at least 2 GPS points") return # Test creating just 3 frames test_frames_folder = os.path.join(project_folder, "test_frames") os.makedirs(test_frames_folder, exist_ok=True) # Extract coordinates lats = np.array([pos['latitude'] for pos in positions[:10]]) # Just first 10 points lons = np.array([pos['longitude'] for pos in positions[:10]]) alts = np.array([pos.get('altitude', 0) for pos in positions[:10]]) # Convert to relative coordinates lat_center = np.mean(lats) lon_center = np.mean(lons) alt_min = np.min(alts) x = (lons - lon_center) * 111320 * np.cos(np.radians(lat_center)) y = (lats - lat_center) * 110540 z = alts - alt_min print(f"✅ Processed coordinates: x={x.min():.1f} to {x.max():.1f}, y={y.min():.1f} to {y.max():.1f}") frame_files = [] # Create 3 test frames for frame_idx in range(3): end_point = (frame_idx + 1) * 3 end_point = min(end_point, len(x)) print(f"Creating frame {frame_idx + 1}, showing {end_point} points...") # Create 3D plot fig = plt.figure(figsize=(10, 8), dpi=100) ax = fig.add_subplot(111, projection='3d') # Plot route up to current point if end_point > 1: ax.plot(x[:end_point], y[:end_point], z[:end_point], 'b-', linewidth=2) ax.scatter(x[:end_point], y[:end_point], z[:end_point], c='blue', s=20) # Current position if end_point > 0: current_idx = end_point - 1 ax.scatter(x[current_idx], y[current_idx], z[current_idx], c='red', s=100, marker='o') # Remaining route if end_point < len(x): ax.plot(x[end_point:], y[end_point:], z[end_point:], 'lightgray', linewidth=1, alpha=0.3) ax.set_xlabel('East-West (m)') ax.set_ylabel('North-South (m)') ax.set_zlabel('Elevation (m)') ax.set_title(f'Test Frame {frame_idx + 1} - Point {end_point}/{len(x)}') # Set view margin = max(np.ptp(x), np.ptp(y)) * 0.1 if np.ptp(x) > 0 else 100 ax.set_xlim(np.min(x) - margin, np.max(x) + margin) ax.set_ylim(np.min(y) - margin, np.max(y) + margin) ax.set_zlim(np.min(z) - 10, np.max(z) + 10) ax.view_init(elev=20, azim=45) ax.grid(True) # Save frame frame_path = os.path.join(test_frames_folder, f"test_frame_{frame_idx:03d}.png") try: plt.savefig(frame_path, dpi=100, bbox_inches='tight', facecolor='white', edgecolor='none', format='png') plt.close(fig) # Check frame if os.path.exists(frame_path): file_size = os.path.getsize(frame_path) print(f"✅ Frame {frame_idx + 1} saved: {file_size} bytes") # Test OpenCV reading test_img = cv2.imread(frame_path) if test_img is not None: h, w, c = test_img.shape print(f"✅ Frame {frame_idx + 1} readable by OpenCV: {w}x{h}") frame_files.append(frame_path) else: print(f"❌ Frame {frame_idx + 1} not readable by OpenCV") else: print(f"❌ Frame {frame_idx + 1} not created") except Exception as e: print(f"❌ Error creating frame {frame_idx + 1}: {e}") plt.close(fig) print(f"Created {len(frame_files)} valid frames") # Test video creation if frame_files: output_video = os.path.join(project_folder, f"test_progressive_{datetime.now().strftime('%H%M%S')}.mp4") # Read first frame for dimensions first_frame = cv2.imread(frame_files[0]) height, width, layers = first_frame.shape print(f"Video dimensions: {width}x{height}") # Create video fourcc = cv2.VideoWriter_fourcc(*'mp4v') video_writer = cv2.VideoWriter(output_video, fourcc, 2.0, (width, height)) if video_writer.isOpened(): for i, frame_file in enumerate(frame_files): frame = cv2.imread(frame_file) if frame is not None: video_writer.write(frame) print(f"✅ Added frame {i+1} to video") else: print(f"❌ Could not read frame {i+1}") video_writer.release() if os.path.exists(output_video): file_size = os.path.getsize(output_video) print(f"✅ Video created: {output_video} ({file_size} bytes)") else: print("❌ Video file not created") else: print("❌ Could not open video writer") # Clean up for frame_file in frame_files: try: os.remove(frame_file) except: pass try: os.rmdir(test_frames_folder) except: pass except Exception as e: print(f"❌ Error: {e}") import traceback traceback.print_exc() if __name__ == "__main__": test_progressive_animation_debug()