Ver código fonte

optimize marker creation

subDesTagesMitExtraKaese 2 anos atrás
pai
commit
42063dec07
3 arquivos alterados com 75 adições e 27 exclusões
  1. 21 10
      static/gps_logger/js/preprocessor.js
  2. 13 6
      templates/gps_logger/upload.html
  3. 41 11
      views.py

+ 21 - 10
static/gps_logger/js/preprocessor.js

@@ -52,7 +52,11 @@ window.onload = function() {
     importFiles(fileList)
   })
 
-  document.getElementById("upload-btn").addEventListener('click', (event) => {
+  const button = document.getElementById("upload-btn");
+  const responseP = document.getElementById("response");
+  button.addEventListener('click', (event) => {
+    button.disabled = true;
+    responseP.textContent = "waiting for response..."
     const xmlhttp = new XMLHttpRequest()
     xmlhttp.open("POST", "markers/create", true);
     xmlhttp.setRequestHeader("Content-type", "application/json")
@@ -60,7 +64,14 @@ window.onload = function() {
     xmlhttp.setRequestHeader('X-CSRFToken', token)
     xmlhttp.onreadystatechange = () => {
       if(xmlhttp.readyState == 4) {
-        alert(xmlhttp.responseText)
+        if(xmlhttp.status == 201)
+          responseP.textContent = "Markers created!"
+        else if(xmlhttp.status == 204)
+          responseP.textContent = "Nothing to change!"
+        else
+          responseP.textContent = `Error code ${xmlhttp.status}`
+        button.disabled = false;
+
       }
     }
     xmlhttp.send(JSON.stringify(markersToUpload))
@@ -69,7 +80,7 @@ window.onload = function() {
 function importFiles(fileList) {
   d = []
   plot = $.plot("#placeholder", d, options);
-  markersToUpload = []
+  markersToUpload = {}
   for (const file of fileList) {
     if(file.name?.toLowerCase().endsWith(".txt"))
       readTxtFile(file)
@@ -117,9 +128,9 @@ function parseNmeaFile(file) {
         if(ggaObj.time != oldTime) {
           oldTime = ggaObj.time
           result.push({
-            timestamp: ggaObj.time,
-            lat: ggaObj.lat,
-            lng: ggaObj.lon,
+            timestamp: obj.time,
+            lat: obj.lat,
+            lng: obj.lon,
             alt: ggaObj.alt,
             hdop: ggaObj.hdop,
             speed: Math.round(obj.speed)
@@ -149,7 +160,7 @@ function parseNmeaFile(file) {
   reader.readAsText(file)
 }
 
-let markersToUpload = [];
+let markersToUpload;
 
 function process(name, markers) {
   d.push({
@@ -165,8 +176,8 @@ function process(name, markers) {
     const dx23 = distance(m2, m3)
     const dx13 = distance(m2, m3)
     const dt12 = (m2.timestamp - m1.timestamp) / 1000
-    const dt23 = (m2.timestamp - m1.timestamp) / 1000
-    const dt13 = (m3.timestamp - m1.timestamp) / 1000
+    const dt23 = (m3.timestamp - m2.timestamp) / 1000
+    const dt13 = dt12 + dt23
     
     if(dt12 > 0 && dx12/dt12 > 50) {// > 50 m/s = 180 km/h
       console.log(`n=${i} ${m1.timestamp} too fast: ${dx12/dt12} m/s`)
@@ -204,7 +215,7 @@ function process(name, markers) {
   plot.setupGrid() //only necessary if your new data will change the axes or grid
   plot.draw()
 
-  markersToUpload = markersToUpload.concat(markers)
+  markersToUpload[name] = markers
 }
 
 function clean(markers) {

+ 13 - 6
templates/gps_logger/upload.html

@@ -28,13 +28,20 @@
 {% endblock %}
 
 {% block content %}
-<input type="file" id="file-selector" accept=".txt, .nmea" multiple />
-
-<div class="demo-container">
-  <div id="placeholder" class="demo-placeholder"></div>
+<div class="news">
+  <p>
+    <input type="file" id="file-selector" accept=".txt, .nmea" multiple />
+  </p>
+
+  <div class="demo-container">
+    <div id="placeholder" class="demo-placeholder"></div>
+  </div>
+  {% csrf_token %}
+  <p>
+    <input type="submit" id="upload-btn" style="visibility: hidden"/>
+  </p>
+  <p id="response"></p>
 </div>
-{% csrf_token %}
-<input type="submit" id="upload-btn" style="visibility: hidden"/>
 {% endblock %}
 
 {% block body %}

+ 41 - 11
views.py

@@ -1,11 +1,14 @@
+import json
+from datetime import datetime
 from django.shortcuts import render
+from django.http import JsonResponse, HttpResponse
+from django.views import View
 from django.contrib.auth.decorators import permission_required
 from django.contrib.auth.mixins import PermissionRequiredMixin
-from rest_framework import generics
 
 from .models import *
-from .serializers import MarkerSerializer
 
+from pprint import pprint
 
 def index(request):
   return render(request, 'gps_logger/index.html')
@@ -14,15 +17,42 @@ def index(request):
 def upload(request):
   return render(request, 'gps_logger/upload.html')
 
-class MarkerCreateView(generics.CreateAPIView, PermissionRequiredMixin):
-  serializer_class = MarkerSerializer
+class MarkerCreateView(View, PermissionRequiredMixin):
   permission_required = ("gps-logger.markers.change")
-  def get_serializer(self, *args, **kwargs):
-    if isinstance(kwargs.get("data", {}), list):
-        kwargs["many"] = True
 
-    return super(MarkerCreateView, self).get_serializer(*args, **kwargs)
+  def post(self, request):
+    status_code = 204
+    data = json.loads(request.body)
+    for file in data:
+      if len(data[file]) == 0:
+        continue
+      objects = [Marker(
+          timestamp=datetime.strptime(x['timestamp'].replace("Z","-0000"), r"%Y-%m-%dT%H:%M:%S.%f%z"),
+          lat = x['lat'],
+          lng = x['lng'],
+          alt = x['alt'],
+          hdop = x.get('hdop', None),
+          speed = x.get('speed', None)
+        ) for x in data[file]]
+      start_date = objects[0].timestamp
+      end_date = objects[-1].timestamp
+      oldMarkers = Marker.objects.filter(timestamp__range=(start_date, end_date)).all()
+      identical = len(oldMarkers) == len(objects)
+      if identical:
+        for i, marker in enumerate(oldMarkers):
+          if marker.timestamp != objects[i].timestamp:
+            print(type(marker.timestamp), type(objects[i].timestamp))
+            identical = False
+            break
 
-class MarkerView(generics.ListAPIView):
-  serializer_class = MarkerSerializer
-  queryset = Marker.objects
+      print(len(oldMarkers), len(objects), identical)      
+      if not identical:
+        oldMarkers.delete()
+        Marker.objects.bulk_create(objects)
+        status_code = 201
+    return HttpResponse(status=status_code)
+
+
+class MarkerView(View):
+  def get(self, request):
+    return JsonResponse(list(Marker.objects.values()), safe=False)