updates preview and pauses
This commit is contained in:
Binary file not shown.
@@ -4,7 +4,7 @@ from kivy.uix.screenmanager import ScreenManager, Screen
|
||||
import os
|
||||
import json
|
||||
from kivy.clock import Clock
|
||||
from kivy.properties import StringProperty, ListProperty, AliasProperty
|
||||
from kivy.properties import StringProperty, NumericProperty, AliasProperty
|
||||
from utils import (
|
||||
generate_key, load_key, encrypt_data, decrypt_data,
|
||||
check_server_settings, save_server_settings,
|
||||
@@ -33,11 +33,13 @@ from selenium.webdriver.chrome.options import Options
|
||||
from PIL import Image
|
||||
import time
|
||||
import os
|
||||
import math
|
||||
|
||||
class CreateAnimationScreen(Screen):
|
||||
project_name = StringProperty("")
|
||||
preview_html_path = StringProperty("") # Path to the HTML file for preview
|
||||
preview_image_path = StringProperty("") # Add this line
|
||||
preview_image_version = NumericProperty(0) # Add this line
|
||||
|
||||
def get_preview_image_source(self):
|
||||
project_folder = os.path.join(RESOURCES_FOLDER, "projects", self.project_name)
|
||||
@@ -46,7 +48,9 @@ class CreateAnimationScreen(Screen):
|
||||
return img_path
|
||||
return "resources/images/track.png"
|
||||
|
||||
preview_image_source = AliasProperty(get_preview_image_source, None, bind=['project_name'])
|
||||
preview_image_source = AliasProperty(
|
||||
get_preview_image_source, None, bind=['project_name', 'preview_image_version']
|
||||
)
|
||||
|
||||
def on_pre_enter(self):
|
||||
# Update the route entries label with the actual number of entries
|
||||
@@ -130,8 +134,10 @@ class CreateAnimationScreen(Screen):
|
||||
popup.open()
|
||||
|
||||
def process_entries(dt):
|
||||
import datetime
|
||||
project_folder = os.path.join(RESOURCES_FOLDER, "projects", self.project_name)
|
||||
positions_path = os.path.join(project_folder, "positions.json")
|
||||
pauses_path = os.path.join(project_folder, "pauses.json")
|
||||
if not os.path.exists(positions_path):
|
||||
label.text = "positions.json not found!"
|
||||
progress.value = 100
|
||||
@@ -164,10 +170,98 @@ class CreateAnimationScreen(Screen):
|
||||
if end_remove > 0:
|
||||
end_remove -= 1
|
||||
|
||||
# Shorten the positions list
|
||||
new_positions = positions[start_remove:len(positions)-end_remove if end_remove > 0 else None]
|
||||
|
||||
# --- PAUSE DETECTION ---
|
||||
pauses = []
|
||||
if new_positions:
|
||||
pause_start = None
|
||||
pause_end = None
|
||||
pause_location = None
|
||||
for i in range(1, len(new_positions)):
|
||||
prev = new_positions[i-1]
|
||||
curr = new_positions[i]
|
||||
# Check if stopped (same location)
|
||||
if curr['latitude'] == prev['latitude'] and curr['longitude'] == prev['longitude']:
|
||||
if pause_start is None:
|
||||
pause_start = prev['deviceTime']
|
||||
pause_location = (prev['latitude'], prev['longitude'])
|
||||
pause_end = curr['deviceTime']
|
||||
else:
|
||||
if pause_start and pause_end:
|
||||
# Calculate pause duration
|
||||
t1 = datetime.datetime.fromisoformat(pause_start.replace('Z', '+00:00'))
|
||||
t2 = datetime.datetime.fromisoformat(pause_end.replace('Z', '+00:00'))
|
||||
duration = (t2 - t1).total_seconds()
|
||||
if duration >= 180:
|
||||
pauses.append({
|
||||
"start_time": pause_start,
|
||||
"end_time": pause_end,
|
||||
"duration_seconds": int(duration),
|
||||
"location": {"latitude": pause_location[0], "longitude": pause_location[1]}
|
||||
})
|
||||
pause_start = None
|
||||
pause_end = None
|
||||
pause_location = None
|
||||
# Check for pause at the end
|
||||
if pause_start and pause_end:
|
||||
t1 = datetime.datetime.fromisoformat(pause_start.replace('Z', '+00:00'))
|
||||
t2 = datetime.datetime.fromisoformat(pause_end.replace('Z', '+00:00'))
|
||||
duration = (t2 - t1).total_seconds()
|
||||
if duration >= 120:
|
||||
pauses.append({
|
||||
"start_time": pause_start,
|
||||
"end_time": pause_end,
|
||||
"duration_seconds": int(duration),
|
||||
"location": {"latitude": pause_location[0], "longitude": pause_location[1]}
|
||||
})
|
||||
|
||||
# --- FILTER PAUSES ---
|
||||
# 1. Remove pauses near start/end
|
||||
start_lat, start_lon = new_positions[0]['latitude'], new_positions[0]['longitude']
|
||||
end_lat, end_lon = new_positions[-1]['latitude'], new_positions[-1]['longitude']
|
||||
filtered_pauses = []
|
||||
for pause in pauses:
|
||||
plat = pause["location"]["latitude"]
|
||||
plon = pause["location"]["longitude"]
|
||||
dist_start = haversine(start_lat, start_lon, plat, plon)
|
||||
dist_end = haversine(end_lat, end_lon, plat, plon)
|
||||
if dist_start < 50 or dist_end < 50:
|
||||
continue # Skip pauses near start or end
|
||||
filtered_pauses.append(pause)
|
||||
|
||||
# 2. Merge pauses close in time and space
|
||||
merged_pauses = []
|
||||
filtered_pauses.sort(key=lambda p: p["start_time"])
|
||||
for pause in filtered_pauses:
|
||||
if not merged_pauses:
|
||||
merged_pauses.append(pause)
|
||||
else:
|
||||
last = merged_pauses[-1]
|
||||
# Time difference in seconds
|
||||
t1 = datetime.datetime.fromisoformat(last["end_time"].replace('Z', '+00:00'))
|
||||
t2 = datetime.datetime.fromisoformat(pause["start_time"].replace('Z', '+00:00'))
|
||||
time_diff = (t2 - t1).total_seconds()
|
||||
# Distance in meters
|
||||
last_lat = last["location"]["latitude"]
|
||||
last_lon = last["location"]["longitude"]
|
||||
plat = pause["location"]["latitude"]
|
||||
plon = pause["location"]["longitude"]
|
||||
dist = haversine(last_lat, last_lon, plat, plon)
|
||||
if time_diff < 300 and dist < 50:
|
||||
# Merge: extend last pause's end_time and duration
|
||||
last["end_time"] = pause["end_time"]
|
||||
last["duration_seconds"] += pause["duration_seconds"]
|
||||
else:
|
||||
merged_pauses.append(pause)
|
||||
pauses = merged_pauses
|
||||
|
||||
progress.value = 100
|
||||
label.text = (
|
||||
f"Entries removable at start: {start_remove}\n"
|
||||
f"Entries removable at end: {end_remove}"
|
||||
f"Entries removable at end: {end_remove}\n"
|
||||
f"Detected pauses: {len(pauses)}"
|
||||
)
|
||||
|
||||
btn_save = Button(text="Save optimized file", background_color=(0.008, 0.525, 0.290, 1))
|
||||
@@ -178,10 +272,11 @@ class CreateAnimationScreen(Screen):
|
||||
layout.add_widget(btn_box)
|
||||
|
||||
def save_optimized(instance):
|
||||
new_positions = positions[start_remove:len(positions)-end_remove if end_remove > 0 else None]
|
||||
with open(positions_path, "w") as f:
|
||||
json.dump(new_positions, f, indent=2)
|
||||
label.text = "File optimized and saved!"
|
||||
with open(pauses_path, "w") as f:
|
||||
json.dump(pauses, f, indent=2)
|
||||
label.text = "File optimized and pauses saved!"
|
||||
btn_save.disabled = True
|
||||
btn_cancel.disabled = True
|
||||
def close_and_refresh(dt):
|
||||
@@ -212,6 +307,7 @@ class CreateAnimationScreen(Screen):
|
||||
|
||||
def set_preview_image_path(path):
|
||||
self.preview_image_path = path
|
||||
self.preview_image_version += 1 # Force AliasProperty to update
|
||||
self.property('preview_image_source').dispatch(self)
|
||||
self.ids.preview_image.reload()
|
||||
# Schedule the processing function
|
||||
@@ -229,3 +325,13 @@ class CreateAnimationScreen(Screen):
|
||||
0.5
|
||||
)
|
||||
|
||||
def haversine(lat1, lon1, lat2, lon2):
|
||||
# Returns distance in meters between two lat/lon points
|
||||
R = 6371000 # Earth radius in meters
|
||||
phi1 = math.radians(lat1)
|
||||
phi2 = math.radians(lat2)
|
||||
dphi = math.radians(lat2 - lat1)
|
||||
dlambda = math.radians(lon2 - lon1)
|
||||
a = math.sin(dphi/2)**2 + math.cos(phi1)*math.cos(phi2)*math.sin(dlambda/2)**2
|
||||
return 2 * R * math.asin(math.sqrt(a))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user