Виджет с усреднёнными точками на карте
This commit is contained in:
@@ -255,6 +255,158 @@ class ShowSourceWithPointsMapView(LoginRequiredMixin, View):
|
||||
return render(request, "mainapp/source_with_points_map.html", context)
|
||||
|
||||
|
||||
class ShowSourceAveragingStepsMapView(LoginRequiredMixin, View):
|
||||
"""View for displaying source averaging steps visualization."""
|
||||
|
||||
def get(self, request, source_id):
|
||||
from ..models import Source
|
||||
from ..utils import calculate_mean_coords, RANGE_DISTANCE
|
||||
|
||||
try:
|
||||
source = Source.objects.prefetch_related(
|
||||
"source_objitems",
|
||||
"source_objitems__parameter_obj",
|
||||
"source_objitems__geo_obj",
|
||||
).get(id=source_id)
|
||||
except Source.DoesNotExist:
|
||||
return redirect("mainapp:home")
|
||||
|
||||
# Получаем все ObjItem, отсортированные по ID (порядок добавления)
|
||||
objitems = source.source_objitems.select_related(
|
||||
"parameter_obj", "geo_obj"
|
||||
).order_by("id")
|
||||
|
||||
# Собираем координаты всех точек
|
||||
original_points = []
|
||||
for obj in objitems:
|
||||
if (
|
||||
not hasattr(obj, "geo_obj")
|
||||
or not obj.geo_obj
|
||||
or not obj.geo_obj.coords
|
||||
):
|
||||
continue
|
||||
param = getattr(obj, "parameter_obj", None)
|
||||
if not param:
|
||||
continue
|
||||
|
||||
original_points.append(
|
||||
{
|
||||
"point": (obj.geo_obj.coords.x, obj.geo_obj.coords.y),
|
||||
"name": obj.name,
|
||||
"frequency": f"{param.frequency} [{param.freq_range}] МГц",
|
||||
"objitem_id": obj.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Воспроизводим алгоритм усреднения
|
||||
averaging_steps = []
|
||||
|
||||
if original_points:
|
||||
# Первая точка становится начальным средним
|
||||
current_avg = original_points[0]["point"]
|
||||
|
||||
# Обрабатываем остальные точки
|
||||
for i, point_data in enumerate(original_points[1:], start=1):
|
||||
current_coord = point_data["point"]
|
||||
|
||||
# Вычисляем новое среднее и расстояние
|
||||
new_avg, distance = calculate_mean_coords(current_avg, current_coord)
|
||||
|
||||
# Сохраняем шаг усреднения
|
||||
averaging_steps.append(
|
||||
{
|
||||
"point": new_avg,
|
||||
"step": i,
|
||||
"distance": round(distance, 2),
|
||||
"within_range": distance <= RANGE_DISTANCE,
|
||||
}
|
||||
)
|
||||
|
||||
# Обновляем текущее среднее
|
||||
current_avg = new_avg
|
||||
|
||||
# Формируем группы для отображения на карте
|
||||
groups = []
|
||||
|
||||
# 1. Исходные точки ObjItem (красный)
|
||||
if original_points:
|
||||
groups.append(
|
||||
{
|
||||
"name": "Исходные точки ГЛ",
|
||||
"points": original_points,
|
||||
"color": "red",
|
||||
}
|
||||
)
|
||||
|
||||
# 2. Промежуточные точки усреднения (оранжевый)
|
||||
if averaging_steps:
|
||||
intermediate_points = [
|
||||
{
|
||||
"point": step["point"],
|
||||
"step": f"Шаг {step['step']}",
|
||||
"distance": f"{step['distance']} км",
|
||||
}
|
||||
for step in averaging_steps[:-1] # Все кроме последней
|
||||
]
|
||||
if intermediate_points:
|
||||
groups.append(
|
||||
{
|
||||
"name": "Промежуточные шаги усреднения",
|
||||
"points": intermediate_points,
|
||||
"color": "orange",
|
||||
}
|
||||
)
|
||||
|
||||
# 3. Финальная усредненная точка (синий)
|
||||
if averaging_steps:
|
||||
final_step = averaging_steps[-1]
|
||||
groups.append(
|
||||
{
|
||||
"name": "Финальная усредненная координата",
|
||||
"points": [
|
||||
{
|
||||
"point": final_step["point"],
|
||||
"step": f"Шаг {final_step['step']} (финальный)",
|
||||
"distance": f"{final_step['distance']} км",
|
||||
}
|
||||
],
|
||||
"color": "blue",
|
||||
}
|
||||
)
|
||||
|
||||
# 4. Координаты источника для сравнения (если есть)
|
||||
source_coord_types = [
|
||||
("coords_average", "Сохраненные усредненные координаты", "green"),
|
||||
("coords_kupsat", "Координаты Кубсата", "purple"),
|
||||
("coords_valid", "Координаты оперативников", "cyan"),
|
||||
("coords_reference", "Координаты справочные", "violet"),
|
||||
]
|
||||
|
||||
for coord_field, label, color in source_coord_types:
|
||||
coords = getattr(source, coord_field)
|
||||
if coords:
|
||||
groups.append(
|
||||
{
|
||||
"name": label,
|
||||
"points": [
|
||||
{
|
||||
"point": (coords.x, coords.y),
|
||||
"source_id": f"Источник #{source.id}",
|
||||
}
|
||||
],
|
||||
"color": color,
|
||||
}
|
||||
)
|
||||
|
||||
context = {
|
||||
"groups": groups,
|
||||
"source_id": source_id,
|
||||
"total_points": len(original_points),
|
||||
"total_steps": len(averaging_steps),
|
||||
}
|
||||
return render(request, "mainapp/source_averaging_map.html", context)
|
||||
|
||||
|
||||
class ClusterTestView(LoginRequiredMixin, View):
|
||||
"""Test view for clustering functionality."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user