diff --git a/rowers/courses.py b/rowers/courses.py index eb8967be..cb028272 100644 --- a/rowers/courses.py +++ b/rowers/courses.py @@ -22,6 +22,80 @@ import xml.etree.ElementTree as et from xml.etree.ElementTree import Element, SubElement, Comment, tostring from xml.dom import minidom +from rowers.models import VirtualRace + +# distance of course from lat_lon in km +def howfaris(lat_lon,course): + coords = course.coord + distance = geo_distance(lat_lon[0],lat_lon[1],coords[0],coords[1])[0] + + return distance + +#whatisnear = 150 + +# get nearest races +def getnearestraces(lat_lon,races,whatisnear=150): + newlist = [] + counter = 0 + for race in races: + if race.course is None: # pragma: no cover + newlist.append(race) + else: + c = race.course + coords = c.coord + distance = howfaris(lat_lon,c) + if distance < whatisnear: + newlist.append(race) + counter += 1 + + if counter>0: + races = newlist + else: + courseraces = races.exclude(course__isnull=True) + orders = [(c.id,howfaris(lat_lon,c.course)) for c in courseraces] + orders = sorted(orders,key = lambda tup:tup[1]) + ids = [id for id,distance in orders[0:4]] + for id, distance in orders[5:]: # pragma: no cover + if distance0: + courses = newlist + elif strict: + courses = newlist + else: + orders = [(c.id,howfaris(lat_lon,c)) for c in courses] + orders = sorted(orders,key = lambda tup:tup[1]) + ids = [id for id,distance in orders[0:4]] + for id, distance in orders[5:]: + if distance 0 and longitude.std() > 0: + return True, latmean,lonmean + + return False, latmean,lonmean + + def workout_summary_to_df( rower, startdate=datetime.datetime(1970,1,1), diff --git a/rowers/forms.py b/rowers/forms.py index 7e18b393..db7daea4 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -1128,27 +1128,28 @@ class PlanSelectForm(forms.Form): "price","shortname" ) - class CourseSelectForm(forms.Form): course = forms.ModelChoiceField(queryset=GeoCourse.objects.filter()) def __init__(self, *args, **kwargs): # pragma: no cover course = kwargs.pop('course',None) manager = kwargs.pop('manager',None) + choices = kwargs.pop('choices',[]) super(CourseSelectForm,self).__init__(*args,**kwargs) + if len(choices)>0: + self.fields['course'].queryset = GeoCourse.objects.filter(id__in=[c.id for c in choices]) if course is not None: d_min = 0.5*course.distance d_max = 2*course.distance country = course.country countries = ['unknown',country] - print(countries) + self.fields['course'].queryset = self.fields['course'].queryset.filter( distance__gt = d_min,distance__lt = d_max, country__in = countries ).exclude(id=course.id) if manager is not None: self.fields['course'].queryset = self.fields['course'].queryset.filter(manager=manager) - print(self.fields['course'].queryset) class WorkoutSingleSelectForm(forms.Form): workout = forms.ModelChoiceField( @@ -1471,30 +1472,36 @@ class RaceResultFilterForm(forms.Form): entrycategory = forms.MultipleChoiceField( choices = [], label = 'Groups', - widget=forms.CheckboxSelectMultiple() + widget=forms.CheckboxSelectMultiple(), + required=False, ) def __init__(self, *args, **kwargs): - if 'records' in kwargs: - records = kwargs.pop('records',None) + records = kwargs.pop('records',None) + groups = kwargs.pop('groups',None) + + super(RaceResultFilterForm,self).__init__(*args,**kwargs) if records: # group - thecategories = [record.entrycategory for record in records] - thecategories = list(set(thecategories)) - if len(thecategories) <= 1: - del self.fields['entrycategory'] + if groups: + thecategories = [record.entrycategory for record in records] + thecategories = list(set(thecategories)) + if len(thecategories) <= 1: + del self.fields['entrycategory'] + else: + categorychoices = [] + for category in thecategories: + if category is not None: + categorychoices.append( + (category.id,category) + ) + self.fields['entrycategory'].choices = categorychoices + self.fields['entrycategory'].initial = [cat[0] for cat in categorychoices] else: - categorychoices = [] - for category in thecategories: - if category is not None: - categorychoices.append( - (category.id,category) - ) - self.fields['entrycategory'].choices = categorychoices - self.fields['entrycategory'].initial = [cat[0] for cat in categorychoices] + del self.fields['entrycategory'] # sex thesexes = [record.sex for record in records] diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 09bac286..f811b63d 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -66,7 +66,7 @@ from rowers.courses import ( ) from rowers import mytypes -from rowers.models import course_spline +from rowers.models import course_spline,VirtualRaceResult import datetime import math @@ -2419,47 +2419,185 @@ def course_map(course): return script,div -def leaflet_chart(lat,lon,name=""): - if lat.empty or lon.empty: # pragma: no cover - return [0,"invalid coordinate data"] +def get_map_script_course( + latmean, + lonmean, + latbegin, + latend, + longbegin, + longend, + scoordinates, + course, + ): + latmean,lonmean,coordinates = course_coord_center(course) + lat_min, lat_max, long_min, long_max = course_coord_maxmin(course) - # Throw out 0,0 - df = pd.DataFrame({ - 'lat':lat, - 'lon':lon - }) - - df = df.replace(0,np.nan) - df = df.loc[(df!=0).any(axis=1)] - df.fillna(method='bfill',axis=0,inplace=True) - df.fillna(method='ffill',axis=0,inplace=True) - lat = df['lat'] - lon = df['lon'] - if lat.empty or lon.empty: # pragma: no cover - return [0,"invalid coordinate data"] - - latmean = lat.mean() - lonmean = lon.mean() - - latbegin = lat[lat.index[0]] - longbegin = lon[lon.index[0]] - latend = lat[lat.index[-1]] - longend = lon[lon.index[-1]] - - coordinates = zip(lat,lon) + coordinates = course_spline(coordinates) scoordinates = "[" - for x,y in coordinates: + for index,row in coordinates.iterrows(): scoordinates += """[{x},{y}], """.format( - x=x, - y=y + x=row['latitude'], + y=row['longitude'] + ) + + scoordinates +="]" + + polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course") + + plabels = '' + + for p in polygons: + coords = polygon_coord_center(p) + + plabels += """ + var marker = L.marker([{latbegin}, {longbegin}]).addTo(mymap); + marker.bindPopup("{name}"); + + """.format( + latbegin = coords[0], + longbegin = coords[1], + name = p.name ) - scoordinates += "]" + pcoordinates = """[ + """ + for p in polygons: + pcoordinates += """[ + [""" + + points = GeoPoint.objects.filter(polygon=p).order_by("order_in_poly") + + for pt in points: + pcoordinates += "[{x},{y}],".format( + x = pt.latitude, + y = pt.longitude + ) + + # remove last comma + pcoordinates = pcoordinates[:-1] + pcoordinates += """] + ], + """ + + pcoordinates += """ + ]""" + + script = """ + + """.format( + latmean=latmean, + lonmean=lonmean, + latbegin = latbegin, + latend=latend, + longbegin=longbegin, + longend=longend, + scoordinates=scoordinates, + pcoordinates=pcoordinates, + plabels=plabels + ) + + return script + + +def get_map_script( + latmean, + lonmean, + latbegin, + latend, + longbegin, + longend, + scoordinates, + ): script = """