Переделал страницу с ObjItem. Теперь работает корректно.
This commit is contained in:
@@ -8,92 +8,121 @@
|
||||
4. Иначе создать новый Source с coords_average = координаты geo_obj
|
||||
"""
|
||||
|
||||
import os
|
||||
import django
|
||||
# import os
|
||||
# import django
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dbapp.settings")
|
||||
django.setup()
|
||||
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dbapp.settings")
|
||||
# django.setup()
|
||||
|
||||
from mainapp.models import ObjItem, Source, CustomUser
|
||||
from django.contrib.gis.geos import Point
|
||||
from django.contrib.gis.measure import D
|
||||
from django.contrib.gis.db.models.functions import Distance
|
||||
# from mainapp.models import ObjItem, Source, CustomUser
|
||||
# from django.contrib.gis.geos import Point
|
||||
# from django.contrib.gis.measure import D
|
||||
# from django.contrib.gis.db.models.functions import Distance
|
||||
|
||||
|
||||
def calculate_distance_degrees(coord1, coord2):
|
||||
"""Вычисляет расстояние между двумя координатами в градусах."""
|
||||
import math
|
||||
# def calculate_distance_degrees(coord1, coord2):
|
||||
# """Вычисляет расстояние между двумя координатами в градусах."""
|
||||
# import math
|
||||
|
||||
# lon1, lat1 = coord1
|
||||
# lon2, lat2 = coord2
|
||||
|
||||
# return math.sqrt((lon2 - lon1) ** 2 + (lat2 - lat1) ** 2)
|
||||
|
||||
|
||||
# def fix_objitems_without_source():
|
||||
# """Исправляет ObjItems без связи с Source."""
|
||||
|
||||
# # Получаем пользователя по умолчанию
|
||||
# default_user = CustomUser.objects.get(id=1)
|
||||
|
||||
# # Получаем все ObjItems без source
|
||||
# objitems_without_source = ObjItem.objects.filter(source__isnull=True)
|
||||
# total_count = objitems_without_source.count()
|
||||
|
||||
# print(f"Найдено {total_count} ObjItems без source")
|
||||
|
||||
# if total_count == 0:
|
||||
# print("Нечего исправлять!")
|
||||
# return
|
||||
|
||||
# fixed_count = 0
|
||||
# new_sources_count = 0
|
||||
|
||||
# for objitem in objitems_without_source:
|
||||
# # Проверяем, есть ли geo_obj
|
||||
# if not hasattr(objitem, 'geo_obj') or not objitem.geo_obj or not objitem.geo_obj.coords:
|
||||
# print(f"ObjItem {objitem.id} не имеет geo_obj или координат, пропускаем")
|
||||
# continue
|
||||
|
||||
# geo_coords = objitem.geo_obj.coords
|
||||
# coord_tuple = (geo_coords.x, geo_coords.y)
|
||||
|
||||
# # Ищем ближайший Source
|
||||
# sources_with_coords = Source.objects.filter(coords_average__isnull=False)
|
||||
|
||||
# closest_source = None
|
||||
# min_distance = float('inf')
|
||||
|
||||
# for source in sources_with_coords:
|
||||
# source_coord = (source.coords_average.x, source.coords_average.y)
|
||||
# distance = calculate_distance_degrees(coord_tuple, source_coord)
|
||||
|
||||
# if distance < min_distance:
|
||||
# min_distance = distance
|
||||
# closest_source = source
|
||||
|
||||
# # Если нашли близкий Source (расстояние <= 0.5 градуса)
|
||||
# if closest_source and min_distance <= 0.5:
|
||||
# objitem.source = closest_source
|
||||
# objitem.save()
|
||||
# print(f"ObjItem {objitem.id} связан с Source {closest_source.id} (расстояние: {min_distance:.4f}°)")
|
||||
# fixed_count += 1
|
||||
# else:
|
||||
# # Создаем новый Source
|
||||
# new_source = Source.objects.create(
|
||||
# coords_average=Point(coord_tuple, srid=4326),
|
||||
# created_by=default_user
|
||||
# )
|
||||
# objitem.source = new_source
|
||||
# objitem.save()
|
||||
# print(f"ObjItem {objitem.id} связан с новым Source {new_source.id}")
|
||||
# fixed_count += 1
|
||||
# new_sources_count += 1
|
||||
|
||||
# print(f"\nГотово!")
|
||||
# print(f"Исправлено ObjItems: {fixed_count}")
|
||||
# print(f"Создано новых Source: {new_sources_count}")
|
||||
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# fix_objitems_without_source()
|
||||
|
||||
|
||||
from geographiclib.geodesic import Geodesic
|
||||
|
||||
def calculate_mean_coords(coord1: tuple, coord2: tuple) -> tuple[tuple, float]:
|
||||
"""
|
||||
Вычисляет среднюю точку между двумя координатами с использованием геодезических вычислений (с учётом эллипсоида).
|
||||
|
||||
:param lat1: Широта первой точки в градусах.
|
||||
:param lon1: Долгота первой точки в градусах.
|
||||
:param lat2: Широта второй точки в градусах.
|
||||
:param lon2: Долгота второй точки в градусах.
|
||||
:return: Словарь с ключами 'lat' и 'lon' для средней точки, и расстояние(dist) в КМ.
|
||||
"""
|
||||
lon1, lat1 = coord1
|
||||
lon2, lat2 = coord2
|
||||
|
||||
return math.sqrt((lon2 - lon1) ** 2 + (lat2 - lat1) ** 2)
|
||||
geod_inv = Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2)
|
||||
azimuth1 = geod_inv['azi1']
|
||||
distance = geod_inv['s12']
|
||||
geod_direct = Geodesic.WGS84.Direct(lat1, lon1, azimuth1, distance / 2)
|
||||
return (geod_direct['lon2'], geod_direct['lat2']), distance/1000
|
||||
|
||||
# Пример использования
|
||||
lat1, lon1 = 56.15465080269812, 38.140518028837285
|
||||
lat2, lon2 = 56.0852, 38.0852
|
||||
midpoint = calculate_mean_coords((lat1, lon1), (lat2, lon2)) #56.15465080269812, 38.140518028837285
|
||||
|
||||
def fix_objitems_without_source():
|
||||
"""Исправляет ObjItems без связи с Source."""
|
||||
|
||||
# Получаем пользователя по умолчанию
|
||||
default_user = CustomUser.objects.get(id=1)
|
||||
|
||||
# Получаем все ObjItems без source
|
||||
objitems_without_source = ObjItem.objects.filter(source__isnull=True)
|
||||
total_count = objitems_without_source.count()
|
||||
|
||||
print(f"Найдено {total_count} ObjItems без source")
|
||||
|
||||
if total_count == 0:
|
||||
print("Нечего исправлять!")
|
||||
return
|
||||
|
||||
fixed_count = 0
|
||||
new_sources_count = 0
|
||||
|
||||
for objitem in objitems_without_source:
|
||||
# Проверяем, есть ли geo_obj
|
||||
if not hasattr(objitem, 'geo_obj') or not objitem.geo_obj or not objitem.geo_obj.coords:
|
||||
print(f"ObjItem {objitem.id} не имеет geo_obj или координат, пропускаем")
|
||||
continue
|
||||
|
||||
geo_coords = objitem.geo_obj.coords
|
||||
coord_tuple = (geo_coords.x, geo_coords.y)
|
||||
|
||||
# Ищем ближайший Source
|
||||
sources_with_coords = Source.objects.filter(coords_average__isnull=False)
|
||||
|
||||
closest_source = None
|
||||
min_distance = float('inf')
|
||||
|
||||
for source in sources_with_coords:
|
||||
source_coord = (source.coords_average.x, source.coords_average.y)
|
||||
distance = calculate_distance_degrees(coord_tuple, source_coord)
|
||||
|
||||
if distance < min_distance:
|
||||
min_distance = distance
|
||||
closest_source = source
|
||||
|
||||
# Если нашли близкий Source (расстояние <= 0.5 градуса)
|
||||
if closest_source and min_distance <= 0.5:
|
||||
objitem.source = closest_source
|
||||
objitem.save()
|
||||
print(f"ObjItem {objitem.id} связан с Source {closest_source.id} (расстояние: {min_distance:.4f}°)")
|
||||
fixed_count += 1
|
||||
else:
|
||||
# Создаем новый Source
|
||||
new_source = Source.objects.create(
|
||||
coords_average=Point(coord_tuple, srid=4326),
|
||||
created_by=default_user
|
||||
)
|
||||
objitem.source = new_source
|
||||
objitem.save()
|
||||
print(f"ObjItem {objitem.id} связан с новым Source {new_source.id}")
|
||||
fixed_count += 1
|
||||
new_sources_count += 1
|
||||
|
||||
print(f"\nГотово!")
|
||||
print(f"Исправлено ObjItems: {fixed_count}")
|
||||
print(f"Создано новых Source: {new_sources_count}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fix_objitems_without_source()
|
||||
print(f"Средняя точка: {midpoint[0]}")
|
||||
print(f"Расстояние: {midpoint[1]} км")
|
||||
Reference in New Issue
Block a user