415 lines
16 KiB
Python
415 lines
16 KiB
Python
from .models import (
|
||
Satellite,
|
||
Standard,
|
||
Polarization,
|
||
Mirror,
|
||
Modulation,
|
||
Geo,
|
||
Parameter,
|
||
SigmaParameter,
|
||
ObjItem,
|
||
CustomUser
|
||
)
|
||
from datetime import datetime, time
|
||
import pandas as pd
|
||
import numpy as np
|
||
from django.contrib.gis.geos import Point
|
||
import json
|
||
import re
|
||
|
||
def get_all_constants():
|
||
sats = [sat.name for sat in Satellite.objects.all()]
|
||
standards = [sat.name for sat in Standard.objects.all()]
|
||
pols = [sat.name for sat in Polarization.objects.all()]
|
||
mirrors = [sat.name for sat in Mirror.objects.all()]
|
||
modulations = [sat.name for sat in Modulation.objects.all()]
|
||
return sats, standards, pols, mirrors, modulations
|
||
|
||
def coords_transform(coords: str):
|
||
lat_part, lon_part = coords.strip().split()
|
||
sign_map = {'N': 1, 'E': 1, 'S': -1, 'W': -1}
|
||
|
||
lat_sign_char = lat_part[-1]
|
||
lat_value = float(lat_part[:-1].replace(",", "."))
|
||
latitude = lat_value * sign_map.get(lat_sign_char, 1)
|
||
|
||
lon_sign_char = lon_part[-1]
|
||
lon_value = float(lon_part[:-1].replace(",", "."))
|
||
longitude = lon_value * sign_map.get(lon_sign_char, 1)
|
||
|
||
return (longitude, latitude)
|
||
|
||
def remove_str(s: str):
|
||
if isinstance(s, str):
|
||
if s.strip() == "-" or s.strip() == "" or s.strip() == " " or "неизв" in s.strip():
|
||
return -1
|
||
return float(s.strip().replace(",", "."))
|
||
return s
|
||
|
||
def fill_data_from_df(df: pd.DataFrame, sat: Satellite):
|
||
try:
|
||
df.rename(columns={'Модуляция ': 'Модуляция'}, inplace=True)
|
||
except Exception as e:
|
||
print(e)
|
||
consts = get_all_constants()
|
||
df.fillna(-1, inplace=True)
|
||
for stroka in df.iterrows():
|
||
geo_point = Point(coords_transform(stroka[1]['Координаты']), srid=4326)
|
||
valid_point = None
|
||
kupsat_point = None
|
||
try:
|
||
if stroka[1]['Координаты объекта'] != -1 and stroka[1]['Координаты Кубсата'] != '+':
|
||
if 'ИРИ' not in stroka[1]['Координаты объекта'] and 'БЛА' not in stroka[1]['Координаты объекта']:
|
||
valid_point = list(map(float, stroka[1]['Координаты объекта'].replace(',', '.').split('. ')))
|
||
valid_point = Point(valid_point[1], valid_point[0], srid=4326)
|
||
if stroka[1]['Координаты Кубсата'] != -1 and stroka[1]['Координаты Кубсата'] != '+':
|
||
kupsat_point = list(map(float, stroka[1]['Координаты Кубсата'].replace(',', '.').split('. ')))
|
||
kupsat_point = Point(kupsat_point[1], kupsat_point[0], srid=4326)
|
||
except KeyError:
|
||
print("В таблице нет столбцов с координатами кубсата")
|
||
try:
|
||
polarization_obj, _ = Polarization.objects.get_or_create(name=stroka[1]['Поляризация'].strip())
|
||
except KeyError:
|
||
polarization_obj, _ = Polarization.objects.get_or_create(name="-")
|
||
freq = remove_str(stroka[1]['Частота, МГц'])
|
||
freq_line = remove_str(stroka[1]['Полоса, МГц'])
|
||
v = remove_str(stroka[1]['Символьная скорость, БОД'])
|
||
mod_obj, _ = Modulation.objects.get_or_create(name=stroka[1]['Модуляция'].strip())
|
||
snr = remove_str(stroka[1]['ОСШ'])
|
||
date = stroka[1]['Дата'].date()
|
||
time_ = stroka[1]['Время']
|
||
if isinstance(time_, str):
|
||
time_ = time(0,0,0)
|
||
timestamp = datetime.combine(date, time_)
|
||
current_mirrors = []
|
||
mirror_1 = stroka[1]['Зеркало 1'].strip().split("\n")
|
||
mirror_2 = stroka[1]['Зеркало 2'].strip().split("\n")
|
||
if len(mirror_1) > 1:
|
||
for mir in mirror_1:
|
||
mir_obj, _ = Mirror.objects.get_or_create(name=mir.strip())
|
||
current_mirrors.append(mir.strip())
|
||
elif mirror_1[0] not in consts[3]:
|
||
mir_obj, _ = Mirror.objects.get_or_create(name=mirror_1[0].strip())
|
||
current_mirrors.append(mirror_1[0].strip())
|
||
if len(mirror_2) > 1:
|
||
for mir in mirror_2:
|
||
mir_obj, _ = Mirror.objects.get_or_create(name=mir.strip())
|
||
current_mirrors.append(mir.strip())
|
||
elif mirror_2[0] not in consts[3]:
|
||
mir_obj, _ = Mirror.objects.get_or_create(name=mirror_2[0].strip())
|
||
current_mirrors.append(mirror_2[0].strip())
|
||
location = stroka[1]['Местоопределение'].strip()
|
||
comment = stroka[1]['Комментарий']
|
||
source = stroka[1]['Объект наблюдения']
|
||
|
||
vch_load_obj, vch_created = Parameter.objects.get_or_create(
|
||
id_satellite=sat,
|
||
polarization=polarization_obj,
|
||
frequency=freq,
|
||
freq_range=freq_line,
|
||
bod_velocity=v,
|
||
modulation=mod_obj,
|
||
snr=snr,
|
||
defaults={'id_user_add': CustomUser.objects.get(id=1)}
|
||
)
|
||
|
||
geo, _ = Geo.objects.get_or_create(
|
||
timestamp=timestamp,
|
||
coords=geo_point,
|
||
defaults={
|
||
'coords_kupsat': kupsat_point,
|
||
'coords_valid': valid_point,
|
||
'location': location,
|
||
'comment': comment,
|
||
'is_average': (comment != -1.0),
|
||
'id_user_add': CustomUser.objects.get(id=1)
|
||
}
|
||
)
|
||
geo.save()
|
||
geo.mirrors.set(Mirror.objects.filter(name__in=current_mirrors))
|
||
|
||
obj_item, _ = ObjItem.objects.get_or_create(
|
||
id_geo=geo,
|
||
id_vch_load=vch_load_obj,
|
||
defaults={
|
||
'name': source,
|
||
'id_user_add': CustomUser.objects.get(id=1),
|
||
# 'id_satellite': sat
|
||
}
|
||
)
|
||
|
||
obj_item.save()
|
||
|
||
|
||
def add_satellite_list():
|
||
sats = ['AZERSPACE 2', 'Amos 4', 'Astra 4A', 'ComsatBW-1', 'Eutelsat 16A',
|
||
'Eutelsat 21B', 'Eutelsat 7B', 'ExpressAM6', 'Hellas Sat 3',
|
||
'Intelsat 39', 'Intelsat 17',
|
||
'NSS 12', 'Sicral 2', 'SkyNet 5B', 'SkyNet 5D', 'Syracuse 4A',
|
||
'Turksat 3A', 'Turksat 4A', 'WGS 10', 'Yamal 402']
|
||
|
||
for sat in sats:
|
||
sat_obj, _ = Satellite.objects.get_or_create(
|
||
name=sat
|
||
)
|
||
sat_obj.save()
|
||
|
||
def parse_string(s: str):
|
||
pattern = r'^(.+?) (-?\d+\,\d+) \[(-?\d+\,\d+)\] ([^\s]+) ([A-Za-z]) - (\d{1,2}\.\d{1,2}\.\d{1,4} \d{1,2}:\d{1,2}:\d{1,2})$'
|
||
match = re.match(pattern, s)
|
||
if match:
|
||
return list(match.groups())
|
||
else:
|
||
raise ValueError("Некорректный формат строки")
|
||
|
||
|
||
def get_point_from_json(filepath: str):
|
||
with open(filepath, encoding='utf-8-sig') as jf:
|
||
data = json.load(jf)
|
||
|
||
for obj in data:
|
||
if not obj.get('bearingBehavior', {}):
|
||
if obj['tacticObjectType'] == "source":
|
||
# if not obj['bearingBehavior']:
|
||
source_id = obj['id']
|
||
name = obj['name']
|
||
elements = parse_string(name)
|
||
sat_name = elements[0]
|
||
freq = elements[1]
|
||
freq_range = elements[2]
|
||
pol = elements[4]
|
||
timestamp = datetime.strptime(elements[-1], '%d.%m.%y %H:%M:%S')
|
||
lat = None
|
||
lon = None
|
||
for pos in data:
|
||
if pos["id"] == source_id and pos["tacticObjectType"] == "position":
|
||
lat = pos["latitude"]
|
||
lon = pos["longitude"]
|
||
break
|
||
print(f"Name - {sat_name}, f - {freq}, f range - {freq_range}, pol - {pol} "
|
||
f"time - {timestamp}, pos - ({lat}, {lon})")
|
||
|
||
|
||
|
||
def get_points_from_csv(file_content):
|
||
import io
|
||
if hasattr(file_content, 'read'):
|
||
content = file_content.read()
|
||
if isinstance(content, bytes):
|
||
content = content.decode('utf-8')
|
||
else:
|
||
if isinstance(file_content, bytes):
|
||
content = content.decode('utf-8')
|
||
else:
|
||
content = file_content
|
||
df = pd.read_csv(io.StringIO(content), sep=";",
|
||
names=['id', 'obj', 'lat', 'lon', 'h', 'time', 'sat', 'norad_id', 'freq', 'f_range', 'et', 'qaul', 'mir_1', 'mir_2', 'mir_3'])
|
||
df[['lat', 'lon', 'freq', 'f_range']] = df[['lat', 'lon', 'freq', 'f_range']].replace(',', '.', regex=True).astype(float)
|
||
df['time'] = pd.to_datetime(df['time'], format='%d.%m.%Y %H:%M:%S')
|
||
for row in df.iterrows():
|
||
row = row[1]
|
||
match row['obj'].split(' ')[-1]:
|
||
case 'V':
|
||
pol = 'Вертикальная'
|
||
case 'H':
|
||
pol = 'Горизонтальная'
|
||
case 'R':
|
||
pol = 'Правая'
|
||
case 'L':
|
||
pol = 'Левая'
|
||
case _:
|
||
pol = '-'
|
||
pol_obj, _ = Polarization.objects.get_or_create(
|
||
name=pol
|
||
)
|
||
sat_obj, _ = Satellite.objects.get_or_create(
|
||
name=row['sat'],
|
||
defaults={'norad': row['norad_id']}
|
||
)
|
||
mir_1_obj, _ = Mirror.objects.get_or_create(
|
||
name=row['mir_1']
|
||
)
|
||
mir_2_obj, _ = Mirror.objects.get_or_create(
|
||
name=row['mir_2']
|
||
)
|
||
mir_lst = [row['mir_1'], row['mir_2']]
|
||
if not pd.isna(row['mir_3']):
|
||
mir_3_obj, _ = Mirror.objects.get_or_create(
|
||
|
||
name=row['mir_3']
|
||
)
|
||
vch_load_obj, _ = Parameter.objects.get_or_create(
|
||
id_satellite=sat_obj,
|
||
polarization=pol_obj,
|
||
frequency=row['freq'],
|
||
freq_range=row['f_range'],
|
||
defaults={'id_user_add': CustomUser.objects.get(id=1)}
|
||
)
|
||
|
||
geo_obj, _ = Geo.objects.get_or_create(
|
||
timestamp=row['time'],
|
||
coords=Point(row['lon'], row['lat'], srid=4326),
|
||
defaults={
|
||
'is_average': False,
|
||
'id_user_add': CustomUser.objects.get(id=1),
|
||
}
|
||
)
|
||
geo_obj.mirrors.set(Mirror.objects.filter(name__in=mir_lst))
|
||
|
||
obj_item_obj, _ = ObjItem.objects.get_or_create(
|
||
name=row['obj'],
|
||
# id_satellite=sat_obj,
|
||
id_vch_load=vch_load_obj,
|
||
id_geo=geo_obj,
|
||
defaults={
|
||
'id_user_add': CustomUser.objects.get(id=1)
|
||
}
|
||
)
|
||
obj_item_obj.save()
|
||
# df = pd.read_csv(filepath, sep=";",
|
||
# names=['id', 'obj', 'lat', 'lon', 'h', 'time', 'sat', 'norad_id', 'freq', 'f_range', 'et', 'qaul', 'mir_1', 'mir_2', 'mir_3'])
|
||
# df[['lat', 'lon', 'freq', 'f_range']] = df[['lat', 'lon', 'freq', 'f_range']].replace(',', '.', regex=True).astype(float)
|
||
# df['time'] = pd.to_datetime(df['time'], format='%d.%m.%Y %H:%M:%S')
|
||
# for row in df.iterrows():
|
||
# row = row[1]
|
||
# match row['obj'].split(' ')[-1]:
|
||
# case 'V':
|
||
# pol = 'Вертикальная'
|
||
# case 'H':
|
||
# pol = 'Горизонтальная'
|
||
# case 'R':
|
||
# pol = 'Правая'
|
||
# case 'L':
|
||
# pol = 'Левая'
|
||
# case _:
|
||
# pol = '-'
|
||
# pol_obj, _ = Polarization.objects.get_or_create(
|
||
# name=pol
|
||
# )
|
||
# sat_obj, _ = Satellite.objects.get_or_create(
|
||
# name=row['sat'],
|
||
# defaults={'norad': row['norad_id']}
|
||
# )
|
||
# mir_1_obj, _ = Mirror.objects.get_or_create(
|
||
# name=row['mir_1']
|
||
# )
|
||
# mir_2_obj, _ = Mirror.objects.get_or_create(
|
||
# name=row['mir_2']
|
||
# )
|
||
# mir_lst = [row['mir_1'], row['mir_2']]
|
||
# if not pd.isna(row['mir_3']):
|
||
# mir_3_obj, _ = Mirror.objects.get_or_create(
|
||
|
||
# name=row['mir_3']
|
||
# )
|
||
# vch_load_obj, _ = Parameter.objects.get_or_create(
|
||
# id_satellite=sat_obj,
|
||
# polarization=pol_obj,
|
||
# frequency=row['freq'],
|
||
# freq_range=row['f_range'],
|
||
# defaults={'id_user_add': CustomUser.objects.get(id=1)}
|
||
# )
|
||
|
||
# geo_obj, _ = Geo.objects.get_or_create(
|
||
# timestamp=row['time'],
|
||
# coords=Point(row['lon'], row['lat'], srid=4326),
|
||
# defaults={
|
||
# 'is_average': False,
|
||
# 'id_user_add': CustomUser.objects.get(id=1),
|
||
# }
|
||
# )
|
||
# geo_obj.mirrors.set(Mirror.objects.filter(name__in=mir_lst))
|
||
|
||
# obj_item_obj, _ = ObjItem.objects.get_or_create(
|
||
# name=row['obj'],
|
||
# # id_satellite=sat_obj,
|
||
# id_vch_load=vch_load_obj,
|
||
# id_geo=geo_obj,
|
||
# defaults={
|
||
# 'id_user_add': CustomUser.objects.get(id=1)
|
||
# }
|
||
# )
|
||
# obj_item_obj.save()
|
||
|
||
|
||
def get_vch_load_from_html(file, sat: Satellite) -> None:
|
||
tables = pd.read_html(file, encoding='windows-1251')
|
||
df = tables[0]
|
||
df = df.drop(0).reset_index(drop=True)
|
||
df.columns = df.iloc[0]
|
||
df = df.drop(0).reset_index(drop=True)
|
||
df.replace('Неизвестно', '-', inplace=True)
|
||
df[['Частота, МГц', 'Полоса, МГц', 'Мощность, дБм']] = df[['Частота, МГц', 'Полоса, МГц', 'Мощность, дБм']].apply(pd.to_numeric)
|
||
df['Время начала измерения'] = df['Время начала измерения'].apply(lambda x: datetime.strptime(x, '%d.%m.%Y %H:%M:%S'))
|
||
df['Время окончания измерения'] = df['Время окончания измерения'].apply(lambda x: datetime.strptime(x, '%d.%m.%Y %H:%M:%S'))
|
||
|
||
for stroka in df.iterrows():
|
||
value = stroka[1]
|
||
if value['Полоса, МГц'] < 0.08:
|
||
continue
|
||
if '-' in value['Символьная скорость']:
|
||
bod_velocity = -1.0
|
||
else:
|
||
bod_velocity = value['Символьная скорость']
|
||
if '-' in value['Сигнал/шум, дБ']:
|
||
snr = - 1.0
|
||
else:
|
||
snr = value['Сигнал/шум, дБ']
|
||
if value['Пакетность'] == 'да':
|
||
pack = True
|
||
elif value['Пакетность'] == 'нет':
|
||
pack = False
|
||
else:
|
||
pack = None
|
||
|
||
mod, _ = Modulation.objects.get_or_create(
|
||
name=value['Модуляция']
|
||
)
|
||
standard, _ = Standard.objects.get_or_create(
|
||
name=value['Стандарт']
|
||
)
|
||
sigma_load, _ = SigmaParameter.objects.get_or_create(
|
||
id_satellite=sat,
|
||
frequency=value['Частота, МГц'],
|
||
freq_range=value['Полоса, МГц'],
|
||
defaults={
|
||
"status": value['Статус'],
|
||
"power": value['Мощность, дБм'],
|
||
"bod_velocity": bod_velocity,
|
||
"modulation": mod,
|
||
"snr": snr,
|
||
"packets": pack,
|
||
"datetime_begin": value['Время начала измерения'],
|
||
"datetime_end": value['Время окончания измерения'],
|
||
}
|
||
|
||
)
|
||
sigma_load.save()
|
||
|
||
def define_ku_transfer(min_freq: float, max_freq: float) -> int | None:
|
||
fss = (10700, 11700)
|
||
dss = (11700, 12750)
|
||
if min_freq + 9750 >= fss[0] and max_freq + 9750 <= fss[1]:
|
||
return 9750
|
||
elif min_freq + 10750 >= dss[0] and max_freq + 10750 <= dss[1]:
|
||
return 10750
|
||
return None
|
||
|
||
def compare_and_link_vch_load(sat_id: Satellite, eps_freq: float, eps_frange: float, ku_range: float):
|
||
item_obj = ObjItem.objects.filter(id_vch_load__id_satellite=sat_id)
|
||
vch_sigma = SigmaParameter.objects.filter(id_satellite=sat_id)
|
||
link_count = 0
|
||
obj_count = len(item_obj)
|
||
for idx, obj in enumerate(item_obj):
|
||
vch_load = obj.id_vch_load
|
||
if vch_load.frequency == -1.0:
|
||
continue
|
||
# if unique_points = Point.objects.order_by('frequency').distinct('frequency')
|
||
for sigma in vch_sigma:
|
||
if abs(sigma.frequency + ku_range - vch_load.frequency) <= vch_load.frequency*eps_freq/100 and abs(sigma.freq_range - vch_load.freq_range) <= vch_load.freq_range*eps_frange/100:
|
||
sigma.parameter = vch_load
|
||
sigma.save()
|
||
link_count += 1
|
||
return obj_count, link_count
|
||
|
||
|