Browse Source

move area calculation to server

subDesTagesMitExtraKaese 2 năm trước cách đây
mục cha
commit
c5b1ad6418

+ 3 - 3
admin.py

@@ -9,9 +9,9 @@ class MarkerAdmin(OSMGeoAdmin):
 
 @admin.register(Trip)
 class TripAdmin(admin.ModelAdmin):
-  list_display = ["name", "description", "startTime", "endTime", "color", "distance", "topSpeed", "avgSpeed"]
-  readonly_fields = ["path", "distance", "topSpeed", "avgSpeed", "ascendHeight", "descendHeight", "movementTime"]
-
+  list_display = ["name", "description", "startTime", "totalTime", "color", "distance"]
+  readonly_fields = ["path", "distance", "topSpeed", "avgSpeed", "ascendHeight", "descendHeight", "movementTime", "totalTime", "center", "line"]
+  exclude = ["path"]
 @admin.register(CensoredLocation)
 class CensoredLocationAdmin(OSMGeoAdmin):
   list_display = ["name", "location", "radius"]

+ 40 - 0
migrations/0010_trip_center_trip_line_trip_totaltime_and_more.py

@@ -0,0 +1,40 @@
+# Generated by Django 4.1.2 on 2022-10-31 21:36
+
+import datetime
+import django.contrib.gis.db.models.fields
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('gps_logger', '0009_alter_marker_options_alter_trip_options_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='trip',
+            name='center',
+            field=django.contrib.gis.db.models.fields.PointField(default=None, srid=4326),
+        ),
+        migrations.AddField(
+            model_name='trip',
+            name='line',
+            field=django.contrib.gis.db.models.fields.LineStringField(default=None, null=True, srid=4326),
+        ),
+        migrations.AddField(
+            model_name='trip',
+            name='totalTime',
+            field=models.DurationField(default=datetime.timedelta(0), verbose_name='Total duration'),
+        ),
+        migrations.AlterField(
+            model_name='trip',
+            name='distance',
+            field=models.FloatField(default=0, verbose_name='Distance in m'),
+        ),
+        migrations.AlterField(
+            model_name='trip',
+            name='movementTime',
+            field=models.DurationField(default=datetime.timedelta(0), verbose_name='Movement duration'),
+        ),
+    ]

+ 8 - 4
models.py

@@ -2,13 +2,13 @@ import math
 from datetime import datetime, timedelta
 
 from django.db import models
-from django.contrib.gis.db.models.fields import PointField
+from django.contrib.gis.db.models.fields import PointField, PolygonField, LineStringField
 from django.contrib.gis.measure import D
 from colorfield.fields import ColorField
 
 class Marker(models.Model):
   timestamp = models.DateTimeField(unique=True)
-  location = PointField(dim=2)
+  location = PointField(dim=2, srid=4326)
   alt = models.FloatField("Altitude")
   hdop = models.IntegerField(null=True, blank=True)
   speed = models.FloatField("Speed in km/h", null=True, blank=True)
@@ -21,13 +21,17 @@ class Trip(models.Model):
   endTime = models.DateTimeField()
   name = models.CharField(max_length=255)
   description = models.TextField(null=True, blank=True)
+  totalTime = models.DurationField("Total duration", default=timedelta(0))
+  center = PointField(dim=2, srid=4326, default=None)
+  line = LineStringField(dim=2, srid=4326, default=None, null=True)
+
   color = ColorField()
   distance = models.FloatField("Distance in m", default=0)
   topSpeed = models.FloatField("Top speed in km/h", default=0)
   avgSpeed = models.FloatField("Average speed in km/h", default=0)
   ascendHeight = models.FloatField("Ascend height in m", default=0)
   descendHeight = models.FloatField("Descend height in m", default=0)
-  movementTime = models.DurationField("Movement time", default=timedelta(0))
+  movementTime = models.DurationField("Movement duration", default=timedelta(0))
 
   path = models.BinaryField("Path", default=bytes())
 
@@ -36,7 +40,7 @@ class Trip(models.Model):
 
 
 class CensoredLocation(models.Model):
-  location = PointField(dim=2)
+  location = PointField(dim=2, srid=4326)
   radius = models.IntegerField(default=800)
   name = models.CharField(max_length=255)
 

+ 0 - 8
static/gps_logger/js/tracks.js

@@ -2,14 +2,6 @@
 class GPS {
   parse(trips) {    
     this.trips = trips
-    for(const trip of this.trips) {
-      trip.totalTime = Math.abs(trip.endTime - trip.startTime)
-      trip.minLat = trip.path.reduce((min, p) => p.lat < min ? p.lat : min, trip.path[0].lat)
-      trip.maxLat = trip.path.reduce((max, p) => p.lat > max ? p.lat : max, trip.path[0].lat)
-      trip.minLng = trip.path.reduce((min, p) => p.lng < min ? p.lng : min, trip.path[0].lng)
-      trip.maxLng = trip.path.reduce((max, p) => p.lng > max ? p.lng : max, trip.path[0].lng)
-      trip.center = trip.path[parseInt(trip.path.length/2)]
-    }
     this.regions = this.getRegions()
     this.data = this.trips.map(t => t.path).reduce((a, b) => a.concat(b), [])
   }

+ 7 - 0
views.py

@@ -103,6 +103,13 @@ def trip_view(request):
       trip['startTime'] = trip['startTime'].timestamp()
       trip['endTime'] = trip['endTime'].timestamp()
       trip['movementTime'] = trip['movementTime'].total_seconds()
+      trip['totalTime'] = trip['totalTime'].total_seconds()
+      trip['center'] = {
+        'lng': trip['center'].x,
+        'lat': trip['center'].y
+      }
+      trip['minLng'], trip['minLat'], trip['maxLng'], trip['maxLat'] = trip['line'].extent
+      del trip['line']
     data = json.dumps(values)
     cache.set('trips', data, 3600*24*30)
   return HttpResponse(data, content_type='application/json')

+ 22 - 8
workers/points2trips.py

@@ -5,7 +5,8 @@ from datetime import datetime, timedelta
 import colorsys
 from math import radians, cos, sin, asin, sqrt
 
-from django.contrib.gis.geos.point import Point
+from django.contrib.gis.geos import Point, LineString
+
 
 from ..models import Marker, Trip
 
@@ -42,22 +43,28 @@ def create_trip(markers: list[Marker]) -> Trip:
       startTime = markers[0].timestamp,
       endTime = markers[-1].timestamp,
       name = f"Trip {markers[0].timestamp}",
-      color = get_path_color(markers[0].timestamp),
+      color = get_path_color(markers[0].timestamp)
     )
-  # elif trip.startTime == markers[0].timestamp and trip.endTime == markers[-1].timestamp:
-  #   data = json.loads(gzip.decompress(trip.path))
-  #   if len(data) == len(markers):
-  #     print("Trip already exists")
-  #     return trip
+  elif trip.startTime == markers[0].timestamp and trip.endTime == markers[-1].timestamp:
+    data = json.loads(gzip.decompress(trip.path))
+    if len(data) > len(markers) * 0.9 and len(data) <= len(markers):
+      print("Trip already exists")
+      return trip
 
   trip.startTime = markers[0].timestamp
   trip.endTime = markers[-1].timestamp
+  trip.totalTime = trip.endTime - trip.startTime
+  center = markers[len(markers)//2].location
+  trip.center = Point(center.x, center.y)
+
   total_distance = 0 # m
   topSpeed = 0 # km/h
   ascendHeight = 0 # m
   descendHeight = 0 # m
   movementTime = timedelta(0)
 
+  minLat = minLon = maxLat = maxLon = None
+
   lastSpeed = 0
   i = 1
 
@@ -80,6 +87,11 @@ def create_trip(markers: list[Marker]) -> Trip:
 
     total_distance += dist
     topSpeed = max(topSpeed, speed)
+
+    minLat = min(minLat, point.location.y) if minLat is not None else point.location.y
+    minLon = min(minLon, point.location.x) if minLon is not None else point.location.x
+    maxLat = max(maxLat, point.location.y) if maxLat is not None else point.location.y
+    maxLon = max(maxLon, point.location.x) if maxLon is not None else point.location.x
     
     if speed > 2.0: # km/h
       movementTime += abs(point.timestamp - prev_point.timestamp)
@@ -97,7 +109,9 @@ def create_trip(markers: list[Marker]) -> Trip:
   trip.ascendHeight = round(ascendHeight, 1) # m
   trip.descendHeight = round(descendHeight, 1) # m
   trip.movementTime = movementTime
-  
+
+  trip.line = LineString((markers[0].location.x, markers[0].location.y), (markers[-1].location.x, markers[-1].location.y))
+
   trip.path = points_to_blob(markers)
 
   return trip