commit
This commit is contained in:
@@ -1,4 +1,17 @@
|
||||
from __future__ import absolute_import
|
||||
from rowers.courseutils import coursetime_paths, coursetime_first, time_in_path
|
||||
import pandas as pd
|
||||
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.utils import geo_distance
|
||||
import rowers.dataprep as dataprep
|
||||
from timezonefinder import TimezoneFinder
|
||||
import numpy as np
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
@@ -25,38 +38,42 @@ from xml.dom import minidom
|
||||
from rowers.models import VirtualRace
|
||||
|
||||
# distance of course from lat_lon in km
|
||||
def howfaris(lat_lon,course):
|
||||
|
||||
|
||||
def howfaris(lat_lon, course):
|
||||
coords = course.coord
|
||||
distance = geo_distance(lat_lon[0],lat_lon[1],coords[0],coords[1])[0]
|
||||
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):
|
||||
|
||||
|
||||
def getnearestraces(lat_lon, races, whatisnear=150):
|
||||
newlist = []
|
||||
counter = 0
|
||||
for race in races:
|
||||
if race.course is None: # pragma: no cover
|
||||
if race.course is None: # pragma: no cover
|
||||
newlist.append(race)
|
||||
else:
|
||||
c = race.course
|
||||
coords = c.coord
|
||||
distance = howfaris(lat_lon,c)
|
||||
distance = howfaris(lat_lon, c)
|
||||
if distance < whatisnear:
|
||||
newlist.append(race)
|
||||
counter += 1
|
||||
|
||||
if counter>0:
|
||||
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 distance<whatisnear:
|
||||
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 distance < whatisnear:
|
||||
ids.append(id)
|
||||
|
||||
for id in ids:
|
||||
@@ -65,28 +82,29 @@ def getnearestraces(lat_lon,races,whatisnear=150):
|
||||
|
||||
return races
|
||||
|
||||
def getnearestcourses(lat_lon,courses,whatisnear=150,strict=False):
|
||||
|
||||
def getnearestcourses(lat_lon, courses, whatisnear=150, strict=False):
|
||||
|
||||
newlist = []
|
||||
counter = 0
|
||||
for c in courses:
|
||||
coords = c.coord
|
||||
distance = howfaris(lat_lon,c)
|
||||
distance = howfaris(lat_lon, c)
|
||||
|
||||
if distance < whatisnear:
|
||||
newlist.append(c)
|
||||
counter += 1
|
||||
|
||||
if counter>0:
|
||||
if counter > 0:
|
||||
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]]
|
||||
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<whatisnear: # pragma: no cover
|
||||
if distance < whatisnear: # pragma: no cover
|
||||
ids.append(id)
|
||||
|
||||
for id in ids:
|
||||
@@ -103,12 +121,6 @@ def prettify(elem):
|
||||
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'}
|
||||
|
||||
@@ -118,46 +130,36 @@ xmlns_uris_dict = {'gx': 'http://www.google.com/kml/ext/2.2',
|
||||
'': "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
|
||||
name = course.findall('.//opengis:name', ns)[0].text
|
||||
try:
|
||||
description = course.findall('.//opengis:description',ns)[0].text
|
||||
description = course.findall('.//opengis:description', ns)[0].text
|
||||
except IndexError:
|
||||
description = ''
|
||||
|
||||
polygonpms = course.findall('.//opengis:Placemark[opengis:Polygon]',ns)
|
||||
polygonpms = course.findall(
|
||||
'.//opengis:Placemark[opengis:Polygon]', ns)
|
||||
polygons = get_polygons(polygonpms)
|
||||
|
||||
courses.append({
|
||||
'name':name,
|
||||
'description':description,
|
||||
'polygons':polygons
|
||||
})
|
||||
'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)
|
||||
name = pm.findall('.//opengis:name', ns)[0].text
|
||||
coordinates = pm.findall('.//opengis:coordinates', ns)
|
||||
if coordinates:
|
||||
cc = coordinates[0].text
|
||||
else: # pragma: no cover
|
||||
else: # pragma: no cover
|
||||
cc = ''
|
||||
|
||||
pointstring = cc.split()
|
||||
@@ -166,15 +168,14 @@ def get_polygons(polygonpms):
|
||||
for s in pointstring:
|
||||
coordinates = s.split(',')
|
||||
points.append({
|
||||
'longitude':float(coordinates[0]),
|
||||
'latitude':float(coordinates[1]),
|
||||
})
|
||||
|
||||
polygons.append({
|
||||
'name':name,
|
||||
'points':points
|
||||
'longitude': float(coordinates[0]),
|
||||
'latitude': float(coordinates[1]),
|
||||
})
|
||||
|
||||
polygons.append({
|
||||
'name': name,
|
||||
'points': points
|
||||
})
|
||||
|
||||
return polygons
|
||||
|
||||
@@ -187,94 +188,96 @@ def coursetokml(course):
|
||||
else:
|
||||
top.attrib['xmlns'] = uri
|
||||
|
||||
document = SubElement(top,'Document')
|
||||
document = SubElement(top, 'Document')
|
||||
name = SubElement(document, 'name')
|
||||
name.text = 'Courses.kml'
|
||||
folder = SubElement(document,'Folder')
|
||||
foldername = SubElement(folder,'name')
|
||||
folder = SubElement(document, 'Folder')
|
||||
foldername = SubElement(folder, 'name')
|
||||
foldername.text = 'Courses'
|
||||
folder2 = SubElement(folder,'Folder')
|
||||
coursename = SubElement(folder2,'name')
|
||||
folder2 = SubElement(folder, 'Folder')
|
||||
coursename = SubElement(folder2, 'name')
|
||||
coursename.text = course.name
|
||||
open = SubElement(folder2,'open')
|
||||
open = SubElement(folder2, 'open')
|
||||
open.text = '1'
|
||||
|
||||
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
|
||||
polygons = GeoPolygon.objects.filter(
|
||||
course=course).order_by("order_in_course")
|
||||
|
||||
polygonsxml = []
|
||||
|
||||
for polygon in polygons:
|
||||
placemark = SubElement(folder2,'Placemark')
|
||||
polygonname = SubElement(placemark,'name')
|
||||
placemark = SubElement(folder2, 'Placemark')
|
||||
polygonname = SubElement(placemark, 'name')
|
||||
polygonname.text = polygon.name
|
||||
p = SubElement(placemark,'Polygon')
|
||||
tessellate = SubElement(p,'tessellate')
|
||||
p = SubElement(placemark, 'Polygon')
|
||||
tessellate = SubElement(p, 'tessellate')
|
||||
tessellate.text = '1'
|
||||
boundary = SubElement(p,'outerBoundaryIs')
|
||||
ring = SubElement(boundary,'LinearRing')
|
||||
coordinates = SubElement(ring,'coordinates')
|
||||
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")
|
||||
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,
|
||||
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)
|
||||
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: # pragma: no cover
|
||||
courses = doc.findall('.//opengis:Document[opengis:Placemark]', ns)
|
||||
if not courses:
|
||||
courses = doc.findall('.//opengis:Placemark',ns)
|
||||
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
|
||||
|
||||
polygonpms = doc.findall(
|
||||
'.//opengis:Placemark[opengis:Polygon]', ns) # pragma: no cover
|
||||
|
||||
return get_polygons(polygonpms) # pragma: no cover
|
||||
|
||||
|
||||
def createcourse(
|
||||
manager,name,polygons,notes=''):
|
||||
manager, name, polygons, notes=''):
|
||||
|
||||
c = GeoCourse(manager=manager,name=name,notes=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 = 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:
|
||||
if i == 0 and j == 0:
|
||||
latitude = point['latitude']
|
||||
longitude = point['longitude']
|
||||
g = geocoder.osm([latitude,longitude],method='reverse')
|
||||
g = geocoder.osm([latitude, longitude], method='reverse')
|
||||
if g.ok:
|
||||
country = g.json['country']
|
||||
else: # pragma: no cover
|
||||
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
|
||||
)
|
||||
latitude=point['latitude'],
|
||||
longitude=point['longitude'],
|
||||
polygon=pp,
|
||||
order_in_poly=j
|
||||
)
|
||||
obj.save()
|
||||
j += 1
|
||||
i += 1
|
||||
@@ -285,66 +288,64 @@ def createcourse(
|
||||
return c
|
||||
|
||||
|
||||
def get_time_course(ws,course): # pragma: no cover
|
||||
def get_time_course(ws, course): # pragma: no cover
|
||||
coursetimeseconds = 0.0
|
||||
coursecompleted = False
|
||||
|
||||
w = ws[0]
|
||||
columns = ['time',' latitude',' longitude','cum_dist']
|
||||
columns = ['time', ' latitude', ' longitude', 'cum_dist']
|
||||
rowdata = dataprep.getsmallrowdata_db(
|
||||
columns,
|
||||
ids = [w.id],
|
||||
ids=[w.id],
|
||||
doclean=False,
|
||||
workstrokesonly=False
|
||||
)
|
||||
|
||||
rowdata.rename(columns = {
|
||||
' latitude':'latitude',
|
||||
' longitude':'longitude',
|
||||
}, inplace=True)
|
||||
|
||||
rowdata.rename(columns={
|
||||
' latitude': 'latitude',
|
||||
' longitude': 'longitude',
|
||||
}, inplace=True)
|
||||
|
||||
rowdata['time'] = rowdata['time']/1000.
|
||||
|
||||
rowdata.fillna(method='backfill',inplace=True)
|
||||
rowdata.fillna(method='backfill', inplace=True)
|
||||
|
||||
rowdata['time'] = rowdata['time']-rowdata.ix[0,'time']
|
||||
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.resample('100ms', on='dt').mean()
|
||||
rowdata = rowdata.interpolate()
|
||||
|
||||
# create path
|
||||
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
|
||||
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)
|
||||
) = coursetime_paths(rowdata, paths)
|
||||
(
|
||||
coursetimefirst,
|
||||
coursemetersfirst,
|
||||
firstcompleted
|
||||
) = coursetime_first(
|
||||
rowdata,paths)
|
||||
rowdata, paths)
|
||||
|
||||
coursetimeseconds = coursetimeseconds-coursetimefirst
|
||||
coursemeters = coursemeters-coursemetersfirst
|
||||
|
||||
return coursetimeseconds,coursemeters,coursecompleted
|
||||
return coursetimeseconds, coursemeters, coursecompleted
|
||||
|
||||
def replacecourse(course1,course2):
|
||||
|
||||
def replacecourse(course1, course2):
|
||||
ps = PlannedSession.objects.filter(course=course1)
|
||||
for p in ps:
|
||||
p.course = course2
|
||||
|
||||
Reference in New Issue
Block a user