perf: Filter search results in DB and use time-based gap detection
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
39
main.py
39
main.py
@@ -567,44 +567,45 @@ async def search(request):
|
|||||||
return web.json_response({'error': 'invalid area format in areas list'}, status=400)
|
return web.json_response({'error': 'invalid area format in areas list'}, status=400)
|
||||||
|
|
||||||
client = sensors_client
|
client = sensors_client
|
||||||
q = f'select "lat", "lon" from owntracks where "acc" < 100 and "name" = \'{name}\' order by time asc'
|
|
||||||
|
where_clauses = []
|
||||||
|
for area in areas:
|
||||||
|
sw = area['southWest']
|
||||||
|
ne = area['northEast']
|
||||||
|
where_clauses.append(f'("lat" >= {sw["lat"]} and "lat" <= {ne["lat"]} and "lon" >= {sw["lng"]} and "lon" <= {ne["lng"]})')
|
||||||
|
|
||||||
|
full_where_clause = ' or '.join(where_clauses)
|
||||||
|
|
||||||
|
q = f'select "lat", "lon" from owntracks where "acc" < 100 and "name" = \'{name}\' and ({full_where_clause}) order by time asc'
|
||||||
points = list(client.query(q).get_points())
|
points = list(client.query(q).get_points())
|
||||||
|
|
||||||
ranges = []
|
ranges = []
|
||||||
current_range = None
|
current_range = None
|
||||||
outside_points_count = 0
|
last_point_dt = None
|
||||||
GAP_THRESHOLD_POINTS = 5
|
# Use a 12-hour gap to distinguish between separate visits
|
||||||
|
GAP_THRESHOLD_HOURS = 12
|
||||||
|
|
||||||
for point in points:
|
for point in points:
|
||||||
is_inside = False
|
|
||||||
if point.get('lat') is not None and point.get('lon') is not None:
|
|
||||||
for area in areas:
|
|
||||||
sw = area['southWest']
|
|
||||||
ne = area['northEast']
|
|
||||||
if sw['lat'] <= point['lat'] <= ne['lat'] and sw['lng'] <= point['lon'] <= ne['lng']:
|
|
||||||
is_inside = True
|
|
||||||
break
|
|
||||||
|
|
||||||
point_time_str = point['time']
|
point_time_str = point['time']
|
||||||
if '.' in point_time_str:
|
if '.' in point_time_str:
|
||||||
point_dt = datetime.strptime(point_time_str, '%Y-%m-%dT%H:%M:%S.%fZ')
|
point_dt = datetime.strptime(point_time_str, '%Y-%m-%dT%H:%M:%S.%fZ')
|
||||||
else:
|
else:
|
||||||
point_dt = datetime.strptime(point_time_str, '%Y-%m-%dT%H:%M:%SZ')
|
point_dt = datetime.strptime(point_time_str, '%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
|
||||||
if is_inside:
|
|
||||||
outside_points_count = 0
|
|
||||||
if current_range is None:
|
if current_range is None:
|
||||||
current_range = {'start': point_dt, 'end': point_dt}
|
current_range = {'start': point_dt, 'end': point_dt}
|
||||||
else:
|
else:
|
||||||
current_range['end'] = point_dt
|
time_diff_hours = (point_dt - last_point_dt).total_seconds() / 3600
|
||||||
else: # outside
|
if time_diff_hours > GAP_THRESHOLD_HOURS:
|
||||||
outside_points_count += 1
|
|
||||||
if current_range is not None and outside_points_count >= GAP_THRESHOLD_POINTS:
|
|
||||||
ranges.append({
|
ranges.append({
|
||||||
'start': int(current_range['start'].timestamp()),
|
'start': int(current_range['start'].timestamp()),
|
||||||
'end': int(current_range['end'].timestamp())
|
'end': int(current_range['end'].timestamp())
|
||||||
})
|
})
|
||||||
current_range = None
|
current_range = {'start': point_dt, 'end': point_dt}
|
||||||
|
else:
|
||||||
|
current_range['end'] = point_dt
|
||||||
|
|
||||||
|
last_point_dt = point_dt
|
||||||
|
|
||||||
if current_range is not None:
|
if current_range is not None:
|
||||||
ranges.append({
|
ranges.append({
|
||||||
|
|||||||
Reference in New Issue
Block a user