Przeglądaj źródła

[locations] Fix proximity stuff

Colin Powell 1 rok temu
rodzic
commit
4cdb6150dc

+ 30 - 5
vrobbler/apps/locations/models.py

@@ -92,18 +92,43 @@ class GeoLocation(ScrobblableMixin):
         )
 
     def has_moved(self, past_points: list["GeoLocation"]) -> bool:
+        """GPS jumps from time to time. This function tries to smooth out
+        when we appear to have flagging our location as having not moved if one of our last
+        3"""
         has_moved = False
+        has_moved_locs = []
         for point in past_points:
             loc_diff = self.loc_diff((point.lat, point.lon))
-            logger.info(f"[locations] {self} is {loc_diff} from {point}")
+            logger.info(
+                f"[locations] checking whether location has moved",
+                extra={"location": self, "loc_diff": loc_diff, "point": point},
+            )
             if (
-                loc_diff[0] < GEOLOC_PROXIMITY
-                or loc_diff[1] < GEOLOC_PROXIMITY
+                loc_diff[0] > GEOLOC_PROXIMITY
+                or loc_diff[1] > GEOLOC_PROXIMITY
             ):
                 logger.info(
-                    f"[locations] {loc_diff} is less than proximity setting {GEOLOC_PROXIMITY}, we've moved"
+                    f"[locations] difference is less than proximity setting, we may have moved",
+                    extra={
+                        "loc_diff": loc_diff,
+                        "point": point,
+                        "geoloc_proximity": GEOLOC_PROXIMITY,
+                    },
                 )
-                has_moved = True
+                has_moved_locs.append(True)
+            else:
+                has_moved_locs.append(False)
+
+        # Sum up all True values, if they're more than half of our locations, we've moved
+        if sum(has_moved_locs) > int(len(past_points) / 2):
+            logger.info(
+                f"[locations] more than half of past points have moved, we've moved",
+                extra={
+                    "has_moved_locs": has_moved_locs,
+                    "past_points": past_points,
+                },
+            )
+            has_moved = True
 
         return has_moved
 

+ 66 - 0
vrobbler/apps/locations/tests/test_models.py

@@ -39,3 +39,69 @@ def test_find_or_create_creates_new():
         {"lat": 44.2345, "lon": -68.2345, "alt": 60.356}
     )
     assert not loc.id == extant.id
+
+
+@pytest.mark.django_db
+def test_found_in_proximity_location():
+    lat = 44.234
+    lon = -69.234
+    loc = GeoLocation.objects.create(lat=lat, lon=lon, altitude=60)
+
+    close = GeoLocation.objects.create(
+        lat=lat + 0.0001, lon=lon - 0.0001, altitude=60
+    )
+    assert close not in loc.in_proximity()
+    assert close in loc.in_proximity(named=False)
+
+
+@pytest.mark.django_db
+def test_not_found_in_proximity_location():
+    lat = 44.234
+    lon = -69.234
+    loc = GeoLocation.objects.create(lat=lat, lon=lon, altitude=60)
+
+    far = GeoLocation.objects.create(
+        lat=lat + 0.0002, lon=lon - 0.0001, altitude=60
+    )
+    assert far not in loc.in_proximity(named=False)
+
+
+@pytest.mark.django_db
+def test_has_moved(caplog):
+    lat = 44.234
+    lon = -69.234
+    loc = GeoLocation.objects.create(lat=lat, lon=lon, altitude=60)
+
+    past1 = GeoLocation.objects.get_or_create(
+        lat=lat + 0.000, lon=lon - 0.000, altitude=60
+    )[0]
+    past2 = GeoLocation.objects.get_or_create(
+        lat=lat + 0.002, lon=lon - 0.002, altitude=60
+    )[0]
+    past3 = GeoLocation.objects.get_or_create(
+        lat=lat + 0.0001, lon=lon - 0.000, altitude=60
+    )[0]
+    last_three = [past1, past2, past3]
+    assert loc.has_moved(last_three)
+
+
+@pytest.mark.django_db
+def test_has_not_moved():
+    lat = 44.234
+    lon = -69.234
+    loc = GeoLocation.objects.create(lat=lat, lon=lon, altitude=60)
+
+    past1 = GeoLocation.objects.get_or_create(
+        lat=lat + 0.00001, lon=lon - 0.0000, altitude=60
+    )[0]
+    past2 = GeoLocation.objects.get_or_create(
+        lat=lat + 0.000, lon=lon - 0.000, altitude=60
+    )[0]
+    past3 = GeoLocation.objects.get_or_create(
+        lat=lat + 0.0000, lon=lon - 0.00001, altitude=60
+    )[0]
+    past4 = GeoLocation.objects.get_or_create(
+        lat=lat + 0.005, lon=lon - 0.0003, altitude=60
+    )[0]
+    last_four = [past1, past2, past3, past4]
+    assert not loc.has_moved(last_four)