diff --git a/rowers/opaque.py b/rowers/opaque.py index bc8c8013..b1b2a80f 100644 --- a/rowers/opaque.py +++ b/rowers/opaque.py @@ -43,6 +43,8 @@ class OpaqueEncoder: def encode_hex(self, i): """Transcode an integer and return it as an 8-character hex string.""" + if i is None: + return None return "%08x" % self.transcode(i) def encode_base64(self, i): # pragma: no cover @@ -51,6 +53,8 @@ class OpaqueEncoder: def decode_hex(self, s): """Decode an 8-character hex string, returning the original integer.""" + if s is None: + return None return self.transcode(int(str(s), 16)) def decode_base64(self, s): # pragma: no cover diff --git a/rowers/templates/map_view.html b/rowers/templates/map_view.html index f4fe8ce6..12561a40 100644 --- a/rowers/templates/map_view.html +++ b/rowers/templates/map_view.html @@ -28,6 +28,22 @@ {{ mapscript|safe }} + {% if courses %} +
+
+Click on a line to see the label. Double click on a line to remove it. Reload to get back all lines.
We show your original GPS coordinates on the course. For course time, we use a finer interpolation, to get the exact time when you crossed the line.
diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 457398eb..711b7fac 100644 Binary files a/rowers/tests/testdata/testdata.tcx.gz and b/rowers/tests/testdata/testdata.tcx.gz differ diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index fe0724b3..a64e7324 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -1337,12 +1337,49 @@ def course_mapcompare_view(request, id=0): except GeoCourse.DoesNotExist: # pragma: no cover raise Http404("Course does not exist") + focususer = encoder.decode_hex(request.GET.get('user',None)) + if focususer: + try: + focususer = Rower.objects.get(id=focususer).id + except Rower.DoesNotExist: + focususer = None + + focususers = request.GET.getlist('users',[]) + focususers = [encoder.decode_hex(f) for f in focususers] + results = VirtualRaceResult.objects.filter( course=course, workoutid__isnull=False, coursecompleted=True, ).order_by("distance", "duration") + competitor_ids = [] + for result in results: + if result.userid not in competitor_ids: + competitor_ids.append(result.userid) + + competitors = Rower.objects.filter(id__in=competitor_ids) + + if focususer: + results2 = results.filter(userid=focususer) + else: + results2 = VirtualRaceResult.objects.none() + + if focususers: + results3 = results.filter(userid__in=focususers) + else: + results3 = VirtualRaceResult.objects.none() + + if results2 or results3: + results = results2 | results3 + + selected_ids = [] + for result in results: + if result.userid not in selected_ids: + selected_ids.append(result.userid) + + selected_users = Rower.objects.filter(id__in=selected_ids) + workoutids = [result.workoutid for result in results] startenddict = {} @@ -1407,7 +1444,9 @@ def course_mapcompare_view(request, id=0): 'results': results, 'active': 'nav-racing', 'teamid': 0, - 'teams': [] + 'teams': [], + 'competitors': competitors, + 'selected_users': selected_users, }) @@ -4660,6 +4699,21 @@ def workout_map_view(request, id=0): if request.user == w.user.user: mayedit = 1 + records = VirtualRaceResult.objects.filter( + workoutid=w.id, userid=w.user.user.id, coursecompleted=True + ) + courses = [] + if records.count() > 0: + courses = list(set([record.course for record in records])) + + has_latlon, lat_mean, lon_mean = dataprep.workout_has_latlon(w.id) + + suggested_courses = getnearestcourses([lat_mean, lon_mean], GeoCourse.objects.all(), whatisnear=25, + strict=True) + + suggested_courses = list(set(courses) ^ set(suggested_courses)) + + return render(request, 'map_view.html', {'mapscript': mapscript, 'workout': w, @@ -4668,6 +4722,8 @@ def workout_map_view(request, id=0): 'active': 'nav-workouts', 'mapdiv': mapdiv, 'mayedit': mayedit, + 'courses': courses, + 'suggested_courses': suggested_courses, })