Files
f1-circuits/models/geo_json/geometry.py
T

57 lines
1.9 KiB
Python

from dataclasses import dataclass
from typing import List, Dict, Any
import numpy as np
@dataclass
class GeoJSONGeometry:
type: str
coordinates: List[tuple[float, float]]
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'GeoJSONGeometry':
return cls(
type=data['type'],
coordinates=data['coordinates']
)
def find_longest_straight(self, window_size=5) -> (List[float], List[float]):
"""Find the longest approximately straight section of the track, including wrap-around."""
max_distance = 0
best_start_idx = 0
n = len(self.coordinates)
# Helper function to check straightness
def is_straight(points, start, end, length):
direction = (end - start) / length
distances = []
for point in points:
projection = start + np.dot(point - start, direction) * direction
distance = np.linalg.norm(point - projection)
distances.append(distance)
return max(distances) < length * 0.05 # 5% tolerance
# Check all possible segments, including wrap-around
for i in range(n):
# Get window_size points, handling wrap-around
segment = []
for j in range(window_size):
idx = (i + j) % n
segment.append(np.array(self.coordinates[idx]))
start = np.array(segment[0])
end = np.array(segment[-1])
length = np.linalg.norm(end - start)
if length > max_distance:
# Check if all points are roughly on the line
if is_straight(segment, start, end, length):
max_distance = length
best_start_idx = i
# Return indices that might wrap around
end_idx = (best_start_idx + window_size) % len(self.coordinates)
return self.coordinates[best_start_idx], self.coordinates[end_idx]