# -*- coding: utf-8 -*- # @Time : 2022/5/14 15:05 # @Author : 臧成龙 # @FileName: login.py # @Software: PyCharm import json from datetime import datetime # from django.core.cache import cache from django.contrib import auth from django.forms import model_to_dict from django.shortcuts import get_object_or_404 from django.db.models.expressions import RawSQL from ninja import Router, ModelSchema, Query, Schema, Field from fuadmin.settings import RADIUS_NM, OWN_SHIP_MMSI, OWN_SHIP_NAME, OWN_SHIP_TYPE from system.models import VDESData, ShipLatestStatus, GpsStatus from utils.fu_jwt import FuJwt from utils.fu_response import FuResponse from utils.request_util import save_login_log from utils.vdes_curd import safe_bulk_upsert, get_nearby_ships from random import uniform, randint from datetime import datetime, timedelta router = Router() class SchemaOut(ModelSchema): class Config: model = VDESData model_exclude = ['id'] #排除字段 # @router.get("/home", response=SchemaOut) @router.get("/home") def get_vdesinfo(request): # 初始化4-5艘船的固定MMSI ship_mmsis = ['413323670', '413323671', '413323672', '413323673', '413323674', '423324323', '423343245'] ship_data = [] # 检查是否是第一次调用,如果是则初始化位置 if not hasattr(get_vdesinfo, 'ship_positions'): # 初始位置在(31.0320, 122.1240)周围30公里范围内 base_lat = 31.0320 base_lng = 122.2240 delta = 0.18 # 约20公里 get_vdesinfo.ship_positions = [] for i, mmsi in enumerate(ship_mmsis): # 初始位置随机分布在基准点周围 initial_lat = round(base_lat + uniform(-delta, delta), 6) initial_lng = round(base_lng + uniform(-delta, delta), 6) initial_course = randint(0, 359) #固定本船初始位置 if mmsi == '413323670': initial_lat = 30.9918 initial_lng = 122.2788 get_vdesinfo.ship_positions.append({ 'mmsi': mmsi, 'lat': initial_lat, 'lng': initial_lng, 'course': initial_course, 'speed': round(uniform(5, 15), 1) # 初始速度5-15节 }) # 更新每艘船的位置 for ship in get_vdesinfo.ship_positions: # 微调位置和航向 ship['lat'] += (uniform(0, 1) + 0.3) * 0.001 ship['lng'] += (uniform(0, 1) + 0.3) * 0.001 ship['course'] = (ship['course'] + uniform(-5, 5)) % 360 # 创建模拟数据 mock_data = { 'mmsi': ship['mmsi'], 'latitude': round(ship['lat'], 6), 'longitude': round(ship['lng'], 6), 'speed': ship['speed'], 'course': ship['course'], 'heading': ship['course'], 'nav_status': 0, 'timestamp': datetime.now(), 'ship_name': f'船舶_{ship["mmsi"][-4:]}', 'ship_type': randint(1, 99), 'draught': round(uniform(5.0, 10.0), 1), 'destination': '上海港', 'eta': datetime.now() + timedelta(hours=randint(1, 24)), 'is_ownship': ship['mmsi'] == '413323670' # 新增字段标识本船 } ship_data.append(mock_data) # print(ship_data) # 批量创建并返回所有船的数据 # VDESData.objects.bulk_create(ship_data) return ship_data # 返回所有船舶数据 def create_vdes_data_batch(count): print('开始模拟') data_list = [] for _ in range(count): mock_data = { 'mmsi': str(randint(336295939, 336295969)), 'latitude': round(uniform(30.5, 31.0), 6), 'longitude': round(uniform(122.0, 123.0), 6), 'speed': round(uniform(0, 30), 1), 'course': randint(0, 359), 'heading': randint(0, 359), 'nav_status': randint(0, 8), 'timestamp': datetime.now(), 'ship_name': f'船舶_{randint(1000, 9999)}', 'ship_type': randint(1, 99), 'draught': round(uniform(1.0, 15.0), 1), 'destination': f'港口_{randint(1, 100)}', 'eta': datetime.now() + timedelta(days=randint(1, 7)), } data_list.append(mock_data) return data_list # 批量创建 ShipLatestStatus.objects.bulk_create(data_list) print('模拟结束') @router.get("/nearby") # def nearby_ships(request, lat: float, lon: float, radius_nm: float = 20.0): def nearby_ships(request): # ship_data_list = create_vdes_data_batch(5) # created, updated = safe_bulk_upsert(ship_data_list) # print(f"操作结果: 新增 {created} 条, 更新 {updated} 条") #查询最新经纬度数据 latest_gps = GpsStatus.objects.order_by('-utc_time').first() lat = latest_gps.latitude lon = latest_gps.longitude radius_nm = RADIUS_NM ships = list(get_nearby_ships(lat, lon, radius_nm)) ownship = ShipLatestStatus( mmsi=OWN_SHIP_MMSI, latitude=latest_gps.latitude, longitude=latest_gps.longitude, speed=latest_gps.speed, course=latest_gps.direction, heading=latest_gps.direction, nav_status=randint(0, 8), timestamp=datetime.now(), ship_name=OWN_SHIP_NAME, ship_type=OWN_SHIP_TYPE, draught=round(uniform(1.0, 15.0), 1), destination='上海港', eta=datetime.now() + timedelta(days=randint(1, 7)) ) ships.append(ownship) result = [] for ship in ships: result.append({ 'mmsi': ship.mmsi, 'latitude': ship.latitude, 'longitude': ship.longitude, 'speed': ship.speed, 'course': ship.course, 'heading': ship.heading, 'nav_status': 0, 'timestamp': datetime.now(), 'ship_name': ship.ship_name, 'ship_type': ship.ship_type, 'draught': ship.draught, 'destination': ship.destination, 'eta': ship.eta, 'is_ownship': ship.mmsi == OWN_SHIP_MMSI }) return result