Skip to content

Commit cbc88eb

Browse files
committed
update map recording id
1 parent fb669a6 commit cbc88eb

1 file changed

Lines changed: 56 additions & 34 deletions

File tree

bats_ai/core/views/recording_location.py

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import TYPE_CHECKING, Any, Literal
55

66
from django.contrib.gis.geos import Polygon
7-
from django.db.models import Case, IntegerField, Q, QuerySet, Value, When
7+
from django.db.models import Q, QuerySet
88
from ninja import Query, Router, Schema
99
from ninja.errors import HttpError
1010

@@ -15,6 +15,7 @@
1515
Recording,
1616
RecordingAnnotation,
1717
)
18+
from bats_ai.core.utils.grts_utils import normalize_sample_frame_id
1819

1920
if TYPE_CHECKING:
2021
from django.http import HttpRequest
@@ -125,40 +126,43 @@ def _get_recording_location_coords(recording: Recording) -> list[float] | None:
125126
return [float(point.x), float(point.y)]
126127

127128

129+
def _recording_grts_lookup_pair(recording: Recording) -> tuple[int, int] | None:
130+
"""Return ``(grts_cell_id, sample_frame_id)`` for GRTS DB lookup, if applicable."""
131+
if recording.grts_cell_id is None:
132+
return None
133+
frame_id = (
134+
recording.sample_frame_id
135+
if recording.sample_frame_id is not None
136+
else DEFAULT_SAMPLE_FRAME_ID
137+
)
138+
normalized = normalize_sample_frame_id(frame_id)
139+
if normalized is None:
140+
normalized = DEFAULT_SAMPLE_FRAME_ID
141+
return (recording.grts_cell_id, normalized)
142+
143+
128144
def _precompute_grts_cell_centroids(
129-
cell_ids: set[int],
130-
) -> dict[int, list[float]]:
131-
"""Precompute centroid coordinates for each `grts_cell_id`.
132-
133-
Choose the same "best" cell as `core/views/grts_cells.py` does,
134-
then compute `[lon, lat]` from its centroid.
135-
"""
136-
if not cell_ids:
145+
pairs: set[tuple[int, int]],
146+
) -> dict[tuple[int, int], list[float]]:
147+
"""Map each ``(grts_cell_id, sample_frame_id)`` to ``[lon, lat]`` centroid."""
148+
if not pairs:
137149
return {}
138150

139-
# Default to Continental US
140-
# (sample_frame_id=DEFAULT_SAMPLE_FRAME_ID). We currently only import
141-
# CONUS GRTS, so this keeps centroid selection aligned with loaded data.
142-
frame_rank = Case(
143-
When(sample_frame_id=DEFAULT_SAMPLE_FRAME_ID, then=Value(0)),
144-
default=Value(1),
145-
output_field=IntegerField(),
146-
)
151+
pair_filter = Q()
152+
for grts_cell_id, sample_frame_id in pairs:
153+
pair_filter |= Q(grts_cell_id=grts_cell_id, sample_frame_id=sample_frame_id)
147154

148-
rows = (
149-
GRTSCells.objects.filter(
150-
grts_cell_id__in=cell_ids,
151-
centroid_4326__isnull=False,
152-
)
153-
.annotate(frame_rank=frame_rank)
154-
.order_by("grts_cell_id", "frame_rank")
155-
.distinct("grts_cell_id")
156-
.values_list("grts_cell_id", "centroid_4326")
157-
)
155+
rows = GRTSCells.objects.filter(
156+
pair_filter,
157+
centroid_4326__isnull=False,
158+
).values_list("grts_cell_id", "sample_frame_id", "centroid_4326")
158159

159160
return {
160-
int(cell_id): [float(centroid.x), float(centroid.y)]
161-
for cell_id, centroid in rows
161+
(int(grts_cell_id), int(sample_frame_id)): [
162+
float(centroid.x),
163+
float(centroid.y),
164+
]
165+
for grts_cell_id, sample_frame_id, centroid in rows
162166
if centroid is not None
163167
}
164168

@@ -210,20 +214,34 @@ def get_recording_locations(
210214
grts_cell_ids=grts_cell_ids,
211215
)
212216

213-
my_list = list(my_qs.only("id", "audio_file", "recording_location", "grts_cell_id", "created"))
217+
my_list = list(
218+
my_qs.only(
219+
"id",
220+
"audio_file",
221+
"recording_location",
222+
"grts_cell_id",
223+
"sample_frame_id",
224+
"created",
225+
)
226+
)
214227
shared_list = list(
215228
shared_qs.only(
216229
"id",
217230
"audio_file",
218231
"recording_location",
219232
"grts_cell_id",
233+
"sample_frame_id",
220234
"created",
221235
)
222236
)
223237
recordings = my_list + shared_list
224238

225-
required_cell_ids = {r.grts_cell_id for r in recordings if r.grts_cell_id is not None}
226-
centroids_by_cell_id = _precompute_grts_cell_centroids(required_cell_ids)
239+
grts_pairs = set()
240+
for r in recordings:
241+
pair = _recording_grts_lookup_pair(r)
242+
if pair is not None:
243+
grts_pairs.add(pair)
244+
centroids_by_pair = _precompute_grts_cell_centroids(grts_pairs)
227245

228246
features: list[dict[str, Any]] = []
229247
for rec in recordings:
@@ -233,14 +251,18 @@ def get_recording_locations(
233251
# When vetting is enabled, we only show the centroid of the
234252
# GRTS cell and not the direct recording location.
235253
if rec.grts_cell_id is not None:
236-
coords = centroids_by_cell_id.get(rec.grts_cell_id)
254+
pair = _recording_grts_lookup_pair(rec)
255+
if pair is not None:
256+
coords = centroids_by_pair.get(pair)
237257
# If we can't resolve a centroid, fall back to recording_location.
238258
if coords is None:
239259
coords = _get_recording_location_coords(rec)
240260
else:
241261
coords = _get_recording_location_coords(rec)
242262
if coords is None and rec.grts_cell_id is not None:
243-
coords = centroids_by_cell_id.get(rec.grts_cell_id)
263+
pair = _recording_grts_lookup_pair(rec)
264+
if pair is not None:
265+
coords = centroids_by_pair.get(pair)
244266

245267
if coords is None:
246268
continue

0 commit comments

Comments
 (0)