diff --git a/network/static/network/calender.js b/network/static/network/calender.js
index a440ca3..d4429d0 100644
--- a/network/static/network/calender.js
+++ b/network/static/network/calender.js
@@ -36,11 +36,12 @@ fetch(url)
container: "map",
initialViewState: {
altitude: 1.5,
- longitude: -27,
- latitude: 0,
- zoom: 1,
+ height: 700,
+ longitude: 80,
+ latitude: 35,
+ zoom: 2,
pitch: 60,
- bearing: 127.511,
+ // bearing: -1.7
},
controller: true,
// onViewStateChange: ({ viewState }) => {
@@ -50,9 +51,9 @@ fetch(url)
new deck.HexagonLayer({
data: validEvents,
getPosition: (d) => [d.longitude, d.latitude],
- radius: 100000,
- elevationScale: 400,
- elevationRange: [0, 10000],
+ radius: 50000,
+ elevationScale: 4000,
+ elevationRange: [0, 100],
extruded: true,
pickable: true,
onHover: ({ object, x, y }) => {
@@ -66,7 +67,6 @@ fetch(url)
tooltip.style.display = "block";
tooltip.style.left = `${x}px`;
tooltip.style.top = `${y}px`;
- // tooltip.innerHTML = `
`;
tooltip.innerHTML = `${curDate}`;
} else {
tooltip.style.display = "none";
diff --git a/network/utils.py b/network/utils.py
index a2aa805..1d19d41 100644
--- a/network/utils.py
+++ b/network/utils.py
@@ -1,4 +1,5 @@
import pandas as pd
+from datetime import datetime, date
def df_to_geojson_vect(
@@ -35,3 +36,50 @@ def get_coords(row):
return (row["target_lat"], row["target_lng"])
else:
return row["source_lat"], row["source_lng"]
+
+
+def iso_to_lat_long(iso_date, start_date="1700-01-01", end_date="1990-12-31"):
+ """
+ Maps an ISO date string or datetime.date to latitude and longitude, ensuring
+ earlier dates are more south (latitude) and earlier days within a year are more west (longitude).
+
+ Args:
+ iso_date (str | datetime.date): An ISO-formatted date string (e.g., "2023-01-01")
+ or a datetime.date object.
+ start_date (str): Start of the date range in ISO format (default: "1900-01-01").
+ end_date (str): End of the date range in ISO format (default: "2100-12-31").
+
+ Returns:
+ tuple: A tuple containing latitude and longitude (both as floats).
+ """
+ try:
+ # Ensure iso_date is a datetime.date object
+ if isinstance(iso_date, str):
+ date_obj = datetime.strptime(iso_date, "%Y-%m-%d").date()
+ elif isinstance(iso_date, date):
+ date_obj = iso_date
+ else:
+ raise ValueError("Invalid input type. Must be a string or datetime.date.")
+
+ # Convert start_date and end_date to datetime.date objects
+ start_date_obj = datetime.strptime(start_date, "%Y-%m-%d").date()
+ end_date_obj = datetime.strptime(end_date, "%Y-%m-%d").date()
+
+ # Ensure date_obj is within range
+ if not (start_date_obj <= date_obj <= end_date_obj):
+ raise ValueError("Date is out of the specified range.")
+
+ # Latitude: Based on the position of the date within the range (0–90)
+ total_days = (end_date_obj - start_date_obj).days
+ date_position = (date_obj - start_date_obj).days / total_days
+ lat = 90 * date_position
+
+ # Longitude: Inverted position of the day within the year (0–180)
+ day_of_year = date_obj.timetuple().tm_yday
+ days_in_year = (date(datetime(date_obj.year, 12, 31).year, 12, 31) - date(datetime(date_obj.year, 1, 1).year, 1, 1)).days + 1
+ day_position = (day_of_year - 1) / days_in_year # Normalize day position in the year
+ lon = 180 * day_position
+
+ return lat, lon
+ except Exception as e:
+ raise ValueError(f"Invalid input: {iso_date}") from e
diff --git a/network/views.py b/network/views.py
index 8fad5c1..b0b6939 100644
--- a/network/views.py
+++ b/network/views.py
@@ -14,7 +14,7 @@
from network.forms import EdgeFilterFormHelper
from network.models import Edge
from network.tables import EdgeTable
-from network.utils import get_coords, df_to_geojson_vect
+from network.utils import get_coords, df_to_geojson_vect, iso_to_lat_long
class NetworkView(TemplateView):
@@ -63,25 +63,22 @@ class EdgeListViews(GenericListView):
def edges_as_calender(request):
query_params = request.GET
- queryset = Edge.objects.filter().exclude(start_date__isnull=True).exclude(start_date__lte="1677-12-31")
+ queryset = (
+ Edge.objects.filter()
+ .exclude(start_date__isnull=True)
+ .exclude(start_date__lte="1500-12-31")
+ )
values_list = [x.name for x in Edge._meta.get_fields()]
qs = EdgeListFilter(request.GET, queryset=queryset).qs
items = list(qs.values_list(*values_list))
df = pd.DataFrame(list(items), columns=values_list)
-
- def map_date_to_lat_lng(date_str):
- date = pd.to_datetime(date_str, errors="coerce")
- if pd.isnull(date):
- return None, None
- year = date.year
- day_of_year = date.dayofyear
- # Map year to latitude (-90 to 90)
- latitude = ((year + 90) % 180) - 90
- # Map day of year to longitude (-180 to 180)
- longitude = (day_of_year % 360) - 180
- return latitude, longitude
-
- df["latitude"], df["longitude"] = zip(*df["start_date"].map(map_date_to_lat_lng))
+ start_date = str(df["start_date"].min())
+ end_date = str(df["start_date"].max())
+ df["latitude"], df["longitude"] = zip(
+ *df["start_date"].map(
+ lambda date: iso_to_lat_long(date, start_date=start_date, end_date=end_date)
+ )
+ )
df["label"] = df[["source_label", "edge_label", "target_label"]].agg(
" ".join, axis=1
)