172 lines
6.0 KiB
Python
172 lines
6.0 KiB
Python
|
|
# -*- 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
|