from django.contrib.gis.db import models from django.contrib.gis import geos from django.db import transaction # Create your models here. from django.contrib.auth.models import User class TrackManager(models.Manager): def get_or_create_from_gpx(cls, obj, user): # Get some Meta data from the gpx file. metadata = obj['metadata'] start_time = metadata['time'] # Get the the track and segments from the gpx file. tracks = obj['trk'] name = tracks['name'] segments = tracks['trkseg'] track, created = cls.model.objects.get_or_create( user=user, start=start_time, name=name) if created: with transaction.atomic(): points = segments['trkpt'] segment = Segment( track=track, time=points[0]['time']) segment.save() for pt in points: lon = float(pt['@lon']) lat = float(pt['@lat']) Point.objects.create( segment=segment, time=pt['time'], elevation=pt['ele'], point=geos.Point(lon, lat)) return created, track class Track(models.Model): user = models.ForeignKey(User, blank=False) start = models.DateTimeField() name = models.CharField(max_length=1024, blank=False) description = models.TextField(blank=True) objects = TrackManager() @property def finish(self): return self.segment_set.order_by("-time")[0].finish def __str__(self): return "[{user}] '{name}' from {start} to {finish}".format( user=self.user.username, name=self.name, start=self.start, finish=self.finish) class Segment(models.Model): track = models.ForeignKey(Track) time = models.DateTimeField() number = models.IntegerField(default=1) @property def finish(self): return self.point_set.order_by("-time")[0].time def __str__(self): return "'{name}' Segment #{number} at {tme}".format( name=self.track.name, number=self.number, tme=self.time) class Point(models.Model): time = models.DateTimeField() elevation = models.DecimalField(max_digits=20, decimal_places=2) segment = models.ForeignKey(Segment) # GeoDjango-specific: a geometry field (MultiPolygonField), and # overriding the default manager with a GeoManager instance. point = models.PointField() objects = models.GeoManager() def __str__(self): return "'{name}' ({lat},{lon}) -> {alt} on {time}".format( lat=self.point.x, lon=self.point.y, alt=self.elevation, time=self.time, name=self.segment.track.name)