190 lines
4.6 KiB
Python
190 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):
|
|
c = GeoCourse(manager=manager,name=name)
|
|
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
|
|
|