Private
Public Access
1
0
Files
rowsandall/rowers/courses.py
2018-02-20 22:50:34 +01:00

193 lines
4.6 KiB
Python

# 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 xml.etree.ElementTree as et
import pandas as pd
ns = {'opengis': 'http://www.opengis.net/kml/2.2'}
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_coord_center(polygon):
points = GeoPoint.objects.filter(polygon=polygon).order_by("order_in_poly")
latitudes = pd.Series([p.latitude for p in points])
longitudes = pd.Series([p.longitude for p in points])
return latitudes.mean(), longitudes.mean()
def course_coord_center(course):
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
latitudes = []
longitudes = []
for p in polygons:
latitude,longitude = polygon_coord_center(p)
latitudes.append(latitude)
longitudes.append(longitude)
latitude = pd.Series(latitudes).median()
longitude = pd.Series(longitudes).median()
coordinates = pd.DataFrame({
'latitude':latitudes,
'longitude':longitudes,
})
return latitude,longitude,coordinates
def course_coord_maxmin(course):
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
latitudes = []
longitudes = []
for p in polygons:
latitude,longitude = polygon_coord_center(p)
latitudes.append(latitude)
longitudes.append(longitude)
lat_min = pd.Series(latitudes).min()
lat_max = pd.Series(latitudes).max()
long_min = pd.Series(longitudes).min()
long_max = pd.Series(longitudes).max()
return lat_min,lat_max,long_min,long_max
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)
return 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
def kmltocourse(f):
doc = et.parse(f)
polygonpms = doc.findall('.//opengis:Placemark[opengis:Polygon]',ns)
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
from geopy.geocoders import Nominatim
geolocator = Nominatim()
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:
loc = geolocator.reverse((point['latitude'],point['longitude']))
country = loc.raw['address']['country']
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
return c