Private
Public Access
1
0
Files
rowsandall/rowers/courses.py
Sander Roosendaal 62d06a2439 lots a small stuff
2021-04-26 19:35:11 +02:00

281 lines
7.5 KiB
Python

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
# 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 rowers.dataprep as dataprep
from rowers.utils import geo_distance
ns = {'opengis': 'http://www.opengis.net/kml/2.2'}
xmlns_uris_dict = {'gx': 'http://www.google.com/kml/ext/2.2',
'kml': 'http://www.google.com/kml/ext/2.2',
'atom': "http://www.w3.org/2005/Atom",
'': "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 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: # pragma: no cover
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')
for prefix, uri in xmlns_uris_dict.items():
if prefix != '':
top.attrib['xmlns:' + prefix] = uri
else:
top.attrib['xmlns'] = uri
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: # pragma: no cover
courses = doc.findall('.//opengis:Document[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) # pragma: no cover
return get_polygons(polygonpms) # pragma: no cover
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.osm([latitude,longitude],method='reverse')
if g.ok:
country = g.json['country']
else: # pragma: no cover
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): # pragma: no cover
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