# 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