From e1cb76f1c65155c3c628bd2b8aee4d23d20d3c60 Mon Sep 17 00:00:00 2001 From: pacnpal <183241239+pacnpal@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:56:28 -0400 Subject: [PATCH] Refactor ParkLocation model to inherit from TrackedModel for enhanced history tracking. Update point handling to temporarily store coordinates as a string. Implement Haversine formula for distance calculation as a placeholder until PostGIS is enabled. Refactor advanced search template to utilize Alpine.js for state management. Enhance search functionality with dynamic view modes and improved filter handling using HTMX. --- apps/parks/models/location.py | 40 +++- templates/search/advanced_search.html | 290 +++++++------------------- 2 files changed, 104 insertions(+), 226 deletions(-) diff --git a/apps/parks/models/location.py b/apps/parks/models/location.py index 034eff49..35880326 100644 --- a/apps/parks/models/location.py +++ b/apps/parks/models/location.py @@ -2,10 +2,11 @@ from django.db import models # from django.contrib.gis.geos import Point # Disabled temporarily for setup import pghistory +from apps.core.history import TrackedModel @pghistory.track() -class ParkLocation(models.Model): +class ParkLocation(TrackedModel): """ Represents the geographic location and address of a park, with PostGIS support. """ @@ -53,15 +54,17 @@ class ParkLocation(models.Model): @property def latitude(self): """Return latitude from point field.""" - if self.point: - return self.point.y + if self.point and ',' in self.point: + # Temporary string format: "longitude,latitude" + return float(self.point.split(',')[1]) return None @property def longitude(self): """Return longitude from point field.""" - if self.point: - return self.point.x + if self.point and ',' in self.point: + # Temporary string format: "longitude,latitude" + return float(self.point.split(',')[0]) return None @property @@ -97,7 +100,9 @@ class ParkLocation(models.Model): if not -180 <= longitude <= 180: raise ValueError("Longitude must be between -180 and 180.") - self.point = Point(longitude, latitude, srid=4326) + # Temporarily store as string until PostGIS is enabled + self.point = f"{longitude},{latitude}" + # self.point = Point(longitude, latitude, srid=4326) def distance_to(self, other_location): """ @@ -106,9 +111,26 @@ class ParkLocation(models.Model): """ if not self.point or not other_location.point: return None - # Use geodetic distance calculation which returns meters, convert to km - distance_m = self.point.distance(other_location.point) - return distance_m / 1000.0 + + # Temporary implementation using Haversine formula + # TODO: Replace with PostGIS distance calculation when enabled + import math + + lat1, lon1 = self.latitude, self.longitude + lat2, lon2 = other_location.latitude, other_location.longitude + + if None in (lat1, lon1, lat2, lon2): + return None + + # Haversine formula + R = 6371 # Earth's radius in kilometers + dlat = math.radians(lat2 - lat1) + dlon = math.radians(lon2 - lon1) + a = (math.sin(dlat/2) * math.sin(dlat/2) + + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * + math.sin(dlon/2) * math.sin(dlon/2)) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) + return R * c def __str__(self): return f"Location for {self.park.name}" diff --git a/templates/search/advanced_search.html b/templates/search/advanced_search.html index a3e771b0..c7383e30 100644 --- a/templates/search/advanced_search.html +++ b/templates/search/advanced_search.html @@ -6,8 +6,22 @@ {% block meta_description %}Find your perfect theme park adventure with our advanced search. Filter by location, thrill level, ride type, and more to discover exactly what you're looking for.{% endblock %} {% block content %} - -
+ +
@@ -25,12 +39,12 @@
+ hx-target="#quick-results" + hx-swap="innerHTML">
@@ -55,7 +69,7 @@ Filters -
-
-
+
-
- Operating + + Operating
- +
0 - 0 + 100+
-