Last active
August 25, 2019 01:17
-
-
Save knabben/c48bcd60b8442714a30e2285cd5c6022 to your computer and use it in GitHub Desktop.
Real time tracking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import json | |
| from channels import Group | |
| from ws.models import LocateObject, LocatePath | |
| from django.core.serializers import serialize | |
| def ws_add(message): | |
| message.reply_channel.send({'accept': True}) | |
| Group("path").add(message.reply_channel) | |
| multi_point = serialize( | |
| 'geojson', LocatePath.objects.all(), | |
| geometry_field='path', fields=('locate',) | |
| ) | |
| Group("path").send({'text': json.dumps(multi_point)}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class LocateObject(models.Model): | |
| name = models.CharField(max_length=30) | |
| start_point = models.PointField() | |
| end_point = models.PointField() | |
| @transaction.atomic | |
| def save(self, *args, **kwargs): | |
| super(LocateObject, self).save(*args, **kwargs) | |
| self.save_legs_path() | |
| def save_legs_path(self): | |
| for direction in self.get_directions(): | |
| path = LocatePath.objects.create_path(self, direction) | |
| for step in direction['legs'][0]['steps']: | |
| LocateLegs.objects.create_leg(self, path, step) | |
| def get_directions(self): | |
| gmaps = googlemaps.Client(key=settings.GOOGLE_MAPS_API) | |
| directions_result = gmaps.directions( | |
| self.start_point.get_coords()[::-1], self.end_point.get_coords()[::-1], | |
| mode='driving', departure_time=datetime.now()) | |
| return directions_result | |
| def __str__(self): | |
| return "{} - {} && {}".format( | |
| self.name, self.start_point, self.end_point) | |
| class LocateMixin(object): | |
| @staticmethod | |
| def create_line_string(points): | |
| return LineString( | |
| map(lambda coords: Point(coords[::-1]), polyline.decode(points))) | |
| class LocatePathManager(LocateMixin, models.Manager): | |
| def create_path(self, locate, direction): | |
| points = direction['overview_polyline']['points'] | |
| path, created = self.get_or_create( | |
| path=LocatePathManager.create_line_string(points), locate=locate) | |
| return path | |
| class LocatePath(models.Model): | |
| locate = models.ForeignKey(LocateObject, related_name='paths') | |
| path = models.LineStringField() | |
| objects = LocatePathManager() | |
| def __str__(self): | |
| return "Path for {}".format(self.locate.id) | |
| class LocateLegManager(LocateMixin, models.Manager): | |
| def create_leg(self, locate, path, step): | |
| distance = float(step['distance']['text'].split(' ')[0]) | |
| points = LocateLegManager.create_line_string(step['polyline']['points']) | |
| duration = step['duration']['text'] | |
| leg, created = LocateLegs.objects.get_or_create( | |
| locate=locate, | |
| locate_path=path, | |
| distance=distance, | |
| duration=duration, | |
| leg_point=points) | |
| return leg | |
| class LocateLegs(models.Model): | |
| locate = models.ForeignKey(LocateObject, related_name='legs') | |
| locate_path = models.ForeignKey(LocatePath) | |
| leg_point = models.LineStringField() | |
| distance = models.FloatField() | |
| duration = models.CharField(max_length=30) | |
| objects = LocateLegManager() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from channels.routing import route | |
| from ws.consumers import ws_message, ws_add, ws_disconnect | |
| channel_routing = [ | |
| route("websocket.connect", ws_add), | |
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def handle(self, *args, **kwargs): | |
| from collections import defaultdict | |
| features = defaultdict(list) | |
| for locate in LocateObject.objects.all(): | |
| features[locate.name] = map( | |
| lambda x: json.loads(x.geojson)['coordinates'], | |
| list(locate.legs.all().values_list('leg_point', flat=True)) | |
| ) | |
| def geo_transform(item): | |
| obj_name, coords = item | |
| return { | |
| "type": "Feature", | |
| "geometry": json.loads(Point(coords).geojson), | |
| "properties": { | |
| "title": obj_name, | |
| "icon": "car" | |
| } | |
| } | |
| legs = min([len(n) for n in features.values()]) | |
| for leg in range(0, legs): | |
| points = map(geo_transform, [ | |
| (k_obj, features[k_obj][leg].pop()) for k_obj in features.keys() | |
| ]) | |
| data = { | |
| "type": "geojson", | |
| "data": { | |
| "type": "FeatureCollection", | |
| "features": points | |
| } | |
| } | |
| Group("path").send({'text': json.dumps(data)}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment