Private
Public Access
1
0

defined basic models and some low level functions

This commit is contained in:
Sander Roosendaal
2018-01-26 11:03:00 +01:00
parent bb48cfb96b
commit 92d69087cf
3 changed files with 234 additions and 2 deletions

73
rowers/courses.py Normal file
View File

@@ -0,0 +1,73 @@
# All the Courses related methods
# Python
from django.utils import timezone
from datetime import datetime
from datetime import timedelta
import time
from django.db import IntegrityError
import uuid
from django.conf import settings
from utils import myqueue
from matplotlib import path
import django_rq
queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('low')
from rowers.models import (
Rower, Workout,
GeoPoint,GeoPolygon, GeoCourse,
)
# low level methods
class InvalidTrajectoryError(Exception):
def __init__(self,value):
self.value=value
def __str__(self):
return repr(self.value)
def polygon_to_path(polygon):
points = GeoPoint.objects.filter(polygon==polygon).order_by(order_in_polygon)
s = []
for point in points:
s.append([point.latitude,point.longitude])
p = path.Path(np.array(s))
return p
def coordinate_in_polygon(latitude,longitude, polygon):
p = polygon_to_path(polygon)
retun p.contains_points([(latitude,longitude)])[0]
def time_in_polygon(df,polygon,maxmin='max'):
# df has timestamp, latitude, longitude
p = polygon_to_path(polygon)
latitude = df.latitude
longitude = df.longitude
f = lambda x: coordinate_in_polygon(x['latitude'],x['longitude'],polygon)
df['inpolygon'] = df.apply(f,axis=1)
mask = df['inpolygon'] == True
if df[mask].empty():
raise InvalidTrajectoryError
if maxmin == 'max':
time = df[mask]['time'].max()
else:
time = df[mask]['time'].min()
return time

View File

@@ -643,6 +643,113 @@ timezones = (
(x,x) for x in pytz.common_timezones
)
# models related to geo data (points, polygon, courses)
class GeoCourse(models.Model):
manager = models.ForeignKey(Rower)
name = models.CharField(max_length=150,blank=True)
class GeoPolygon(models.Model):
course = models.ForeignKey(GeoCourse, blank=True)
order_in_course = models.IntegerField(default=0)
# Need error checking to insert new polygons into existing course (all later polygons
# increase there order_in_course number
class GeoPoint(models.Model):
latitude = models.FloatField(default=0)
longitude = models.FloatField(default=0)
polygon = models.ForeignKey(GeoPolygon,blank=True)
order_in_poly = models.IntegerField(default=0)
# need error checking to "insert" new point into existing polygon? This affects order_in_poly
# of multiple GeoPoint instances
# models related to training planning - draft
# Do we need a separate class TestTarget?
class TrainingTarget(models.Model):
rower = models.ForeignKey(Rower)
name = models.CharField(max_length=150,blank=True)
date = models.DateField(
default=timezone.now()+datetime.timedelta(days=182))
notes = models.TextField(max_length=300,blank=True)
# SportTracks has a TrainingGoal like this
#class TrainingGoal(models.Model):
# rower = models.ForeignKey(Rower)
# name = models.CharField(max_length=150,blank=True)
# startdate = models.DateField(default=timezone.now)
# enddate = models.DateField(
# default=timezone.now()+datetime.timedelta(days=28))
# goalmetric = models.CharField(max_length=150,default='rower',
# choices = modechoices)
# value = models.IntegerValue(default=1)
# I think we can use PlannedSession for that (in challenge mode)
# although such a TrainingGoal could have automatically calculated
# values without needing the user to assign
class TrainingPlan(models.Model):
rower = models.ForeignKey(Rower)
name = models.CharField(max_length=150,blank=True)
target = models.ForeignKey(TrainingTarget,blank=True)
startdate = models.DateField(default=timezone.now)
enddate = models.DateField(
default=timezone.now()+datetime.timedelta(days=182))
cycletypechoices = (
('filler','System Defined'),
('userdefined','User Defined')
)
class TrainingMacroCycle(models.Model):
plan = models.ForeignKey(TrainingPlan)
name = models.CharField(max_length=150,blank=True)
startdate = models.DateField(default=timezone.now)
enddate = models.DateField(
default=timezone.now()+datetime.timedelta(days=182))
notes = models.TextField(max_length=300,blank=True)
type = models.CharField(default='filler',
choices=cycletypechoices,
max_length=150)
class TrainingMesoCycle(models.Model):
plan = models.ForeignKey(TrainingMacroCycle)
name = models.CharField(max_length=150,blank=True)
startdate = models.DateField(default=timezone.now)
enddate = models.DateField(
default=timezone.now()+datetime.timedelta(days=182))
notes = models.TextField(max_length=300,blank=True)
type = models.CharField(default='filler',
choices=cycletypechoices,
max_length=150)
class TrainingMicroCycle(models.Model):
plan = models.ForeignKey(TrainingMesoCycle)
name = models.CharField(max_length=150,blank=True)
startdate = models.DateField(default=timezone.now)
enddate = models.DateField(
default=timezone.now()+datetime.timedelta(days=182))
notes = models.TextField(max_length=300,blank=True)
type = models.CharField(default='filler',
choices=cycletypechoices,
max_length=150)
# Needs some error checking
# - Microcycles should not overlap with other microcycles, same for MesoCycles, MacroCycles
# - When a TrainingPlan is created, it should create 1 "collector" Macro, Meso & MicroCycle - this is invisible for users who choose to not use cycles
# - When a new Microcycle is inserted, the "collector" cycle is automatically adjusted to "go out of the way" of the new MicroCycle - and similar for Macro & Meso
# - If the entire MesoCycle is filled with user defined MicroCycles - there are no "filler" MicroCycles
# - Sessions are automatically linked to the correct Cycles based on their start/end date - no need for a hard link
# Cycle error checking goes in forms
# model for Planned Session (Workout, Challenge, Test)
class PlannedSession(models.Model):
@@ -721,7 +828,7 @@ class PlannedSession(models.Model):
max_length=150)
hasranking = models.BooleanField(default=False)
class PlannedSessionForm(ModelForm):
class Meta:
model = PlannedSession
@@ -737,6 +844,19 @@ class PlannedSessionForm(ModelForm):
timezone.now().year-1,timezone.now().year+1)),
}
def __unicode__(self):
name = self.name
startdate = self.startdate
enddate = self.enddate
stri = u'{n} {s} - {e}'.format(
s = startdate.strftime('%Y-%m-%d'),
e = enddate.strftime('%Y-%m-%d'),
n = name,
)
return stri
# Workout
class Workout(models.Model):
@@ -1438,7 +1558,7 @@ class RowerForm(ModelForm):
# optionally sends a tweet to our twitter account
class SiteAnnouncement(models.Model):
created = models.DateField(default=timezone.now)
announcement = models.TextField(max_length=140)
announcement = models.TextField(max_length=280)
expires = models.DateField(default=timezone.now)
modified = models.DateField(default=timezone.now)
dotweet = models.BooleanField(default=False)

39
rowers/plannedsessions.py Normal file
View File

@@ -0,0 +1,39 @@
# Python
from django.utils import timezone
from datetime import datetime
from datetime import timedelta
import time
from django.db import IntegrityError
import uuid
from django.conf import settings
from utils import myqueue
import django_rq
queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('low')
from rowers.models import (
Rower, Workout,
GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle,
TrainingPlan,
)
# Low Level functions - to be called by higher level methods
# dummies for now
def submit_workout(w,ps):
return 1
def remove_workout_plannedsession(w,ps):
return 1
def rank_results(ps):
return 1
def add_team(t,ps):
return 1
def add_rower(r,ps):
return 1