# 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 import geocoder from matplotlib import path import xml.etree.ElementTree as et from xml.etree.ElementTree import Element, SubElement, Comment, tostring from xml.dom import minidom def prettify(elem): """Return a pretty-printed XML string for the Element. """ rough_string = tostring(elem, 'utf-8') reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent=" ") import pandas as pd import numpy as np from timezonefinder import TimezoneFinder import dataprep from rowers.utils import geo_distance ns = {'opengis': 'http://www.opengis.net/kml/2.2'} from rowers.models import ( Rower, Workout, GeoPoint,GeoPolygon, GeoCourse, course_length,course_coord_center,course_coord_maxmin, polygon_coord_center,PlannedSession, polygon_to_path,coordinate_in_path ) from utils import geo_distance from rowers.courseutils import coursetime_paths, coursetime_first,time_in_path def crewnerdcourse(doc): courses = [] for course in doc: name = course.findall('.//opengis:name',ns)[0].text try: description = course.findall('.//opengis:description',ns)[0].text except IndexError: description = '' polygonpms = course.findall('.//opengis:Placemark[opengis:Polygon]',ns) polygons = get_polygons(polygonpms) courses.append({ 'name':name, 'description':description, 'polygons':polygons }) return courses def get_polygons(polygonpms): polygons = [] for pm in polygonpms: name = pm.findall('.//opengis:name',ns)[0].text coordinates = pm.findall('.//opengis:coordinates',ns) if coordinates: cc = coordinates[0].text else: cc = '' pointstring = cc.split() points = [] for s in pointstring: coordinates = s.split(',') points.append({ 'longitude':float(coordinates[0]), 'latitude':float(coordinates[1]), }) polygons.append({ 'name':name, 'points':points }) return polygons def coursetokml(course): top = Element('kml') document = SubElement(top,'Document') name = SubElement(document, 'name') name.text = 'Courses.kml' folder = SubElement(document,'Folder') foldername = SubElement(folder,'name') foldername.text = 'Courses' folder2 = SubElement(folder,'Folder') coursename = SubElement(folder2,'name') coursename.text = course.name open = SubElement(folder2,'open') open.text = '1' polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course") polygonsxml = [] for polygon in polygons: placemark = SubElement(folder2,'Placemark') polygonname = SubElement(placemark,'name') polygonname.text = polygon.name p = SubElement(placemark,'Polygon') tessellate = SubElement(p,'tessellate') tessellate.text = '1' boundary = SubElement(p,'outerBoundaryIs') ring = SubElement(boundary,'LinearRing') coordinates = SubElement(ring,'coordinates') coordinates.text = '' points = GeoPoint.objects.filter(polygon=polygon).order_by("order_in_poly") for point in points: coordinates.text += '{lon},{lat},0 '.format( lat = point.latitude, lon = point.longitude, ) coordinates.text += '{lon},{lat},0'.format( lat = points[0].latitude, lon = points[0].longitude, ) return prettify(top) def kmltocourse(f): doc = et.parse(f) courses = doc.findall('.//opengis:Folder[opengis:Placemark]',ns) if not courses: courses = doc.findall('.//opengis:Placemark',ns) if courses: return crewnerdcourse(courses) polygonpms = doc.findall('.//opengis:Placemark[opengis:Polygon]',ns) return get_polygons(polygonpms) def createcourse( manager,name,polygons,notes=''): c = GeoCourse(manager=manager,name=name,notes=notes) c.save() i = 0 for p in polygons: pp = GeoPolygon(course=c,order_in_course=i,name=p['name']) pp.save() j = 0 for point in p['points']: if i==0 and j==0: latitude = point['latitude'] longitude = point['longitude'] g = geocoder.google([latitude,longitude],method='reverse') if g.ok: address = g.raw['address_components'] country = 'unknown' for a in address: if 'country' in a['types']: country = a['long_name'] else: country = 'unknown' c.country = country c.save() obj = GeoPoint( latitude = point['latitude'], longitude = point['longitude'], polygon = pp, order_in_poly = j ) obj.save() j += 1 i += 1 c.distance = int(course_length(c)) c.save() return c def get_time_course(ws,course): coursetimeseconds = 0.0 coursecompleted = False w = ws[0] columns = ['time',' latitude',' longitude','cum_dist'] rowdata = dataprep.getsmallrowdata_db( columns, ids = [w.id], doclean=False, workstrokesonly=False ) rowdata.rename(columns = { ' latitude':'latitude', ' longitude':'longitude', }, inplace=True) rowdata['time'] = rowdata['time']/1000. rowdata.fillna(method='backfill',inplace=True) rowdata['time'] = rowdata['time']-rowdata.ix[0,'time'] # we may want to expand the time (interpolate) rowdata['dt'] = rowdata['time'].apply( lambda x: timedelta(seconds=x) ) rowdata = rowdata.resample('100ms',on='dt').mean() rowdata = rowdata.interpolate() # create path polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course") paths = [] for polygon in polygons: path = polygon_to_path(polygon) paths.append(path) ( coursetimeseconds, coursemeters, coursecompleted, ) = coursetime_paths(rowdata,paths) ( coursetimefirst, coursemetersfirst, firstcompleted ) = coursetime_first( rowdata,paths) coursetimeseconds = coursetimeseconds-coursetimefirst coursemeters = coursemeters-coursemetersfirst return coursetimeseconds,coursemeters,coursecompleted def replacecourse(course1,course2): ps = PlannedSession.objects.filter(course=course1) for p in ps: p.course = course2 p.save() course1.delete() return 1