diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d70f6f4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,111 @@ +*.pickle + +brouter + +.\#* + +\#*\# + +*~ + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ diff --git a/model.py b/model.py index 8f639fb..abe4443 100644 --- a/model.py +++ b/model.py @@ -3,11 +3,12 @@ Object-Document Map for bike model """ from mongoengine import Document, DateTimeField, GeoPointField, \ FloatField, connection -from road_agent import Agent import datetime -from LatLon import LatLon, Latitude, Longitude +from LatLon23 import LatLon, Latitude, Longitude +from geopy import distance +# TODO: instead of centroid use speed and bearing of flockers to create a vector, point rider towards it class Flock: """ Flock object is created from a list of agents @@ -43,36 +44,46 @@ class Bike(Document): def __init__(self, *args, **kwargs): super(Document, self).__init__(*args, **kwargs) - - self.agent = Agent(point=LatLon(self.point[1], - self.point[0]), - dest=LatLon(self.destination[1], - self.destination[0]), - router=None) - self.db = connection.get_db() - def update(self, lat, lon): + def update(self, lat, lon, speed, bearing): self.point = (lon, lat) - - tdelta = datetime.datetime.now() - self.last_update - seconds = tdelta.total_seconds() - new_point = LatLon(Latitude(lat), Longitude(lon)) - distance = abs(self.agent.point().distance(new_point)) / 1000.0 - self.agent.update(new_point) - - self.speed = distance / seconds + self.speed = speed + self.bearing = bearing self.save() + def heading_to(self, point): + s = LatLon(Latitude(self.point[1]), Longitude(self.point[0])) + t = LatLon(Latitude(point[1]), Longitude(point[0])) + return s.heading_initial(t) + + def distance_to(self, point): + return distance.geodesic(self.get_point(), + (point[1], + point[0])).meters + + + def get_point(self): + return (self.point[1], + self.point[0]) + + def get_dest(self): + return (self.destination[1], + self.destination[0]) + + def find_flock(self, point_altruism=0.1, dest_altruism=0.2): """ :return: list of Bike objects """ - voyage_len = self.agent.distance_to(self.agent.destination()) + trip_len = distance.geodesic(self.get_point(), self.get_dest()).meters - local_radius = voyage_len * point_altruism - destination_radius = voyage_len * dest_altruism + local_radius = trip_len * point_altruism + destination_radius = trip_len * dest_altruism + + + # TODO: filter by timestamp # these are bikes around me local = [bike for bike in @@ -105,10 +116,11 @@ class Bike(Document): """ flock = Flock(self.find_flock()) if flock.size > 1: # no flocking with self! - return {'flock_heading': self.agent.heading_to(flock.centroid), - 'flock_distance': self.agent.distance_to(flock.centroid), + flock_heading: self.heading_to(flock.centroid) + flock_distance: distance.geodesic(self.point, self.destination).meters + return {'flock_heading': flock_heading, + 'flock_distance': flock_distance, 'flock_avg_speed': flock.mean_speed, 'flock_size': flock.size} else: return {} - diff --git a/requirements.txt b/requirements.txt index aba8ac3..d45e39f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ flask flask-mongoengine -road-agent==0.0.3 +LatLon23 +geopy diff --git a/server.py b/server.py index b68f06e..b5368f6 100644 --- a/server.py +++ b/server.py @@ -8,6 +8,7 @@ app = Flask(__name__) db = MongoEngine(app) +# TODO: at registration give current location @app.route("/register/") def register(): dest_lat = request.args.get('dest_lat', None) @@ -25,6 +26,7 @@ def register(): return jsonify(bike_id=str(bike.id)) +# TODO: recieve gps bearing and speed @app.route("/update//") def update(bike_id): @@ -32,11 +34,13 @@ def update(bike_id): lat = float(request.args.get('lat', None)) lon = float(request.args.get('lon', None)) + speed = float(request.args.get('speed', None)) + bearing = float(request.args.get('bearing', None)) - bike.update(lat, lon) - + + bike.update(lat, lon, speed, bearing) return jsonify( - dest_heading=bike.agent.heading_to(bike.agent.destination()), - dest_distance=bike.agent.distance_to(bike.agent.destination()), + dest_heading=bike.heading_to(bike.destination), + dest_distance=bike.distance_to(bike.destination), speed=bike.speed, **bike.flock_data())