Trasu z GPX nahravat do DB

This commit is contained in:
Michal Kváček
2024-07-25 19:50:09 +02:00
parent e541508f75
commit 10bc0847b6
10 changed files with 231 additions and 81 deletions
@@ -10,8 +10,8 @@ async def load_flight_durations(ids: List[int]):
select(
models.Flight.id,
func.timediff(models.Flight.landing_datetime, models.Flight.takeoff_datetime).label("diff"),
func.coalesce(func.sum(models.FlightTrack.landing_duration), 0).label("landing_duration")
).join(models.Flight.track, isouter=True)
func.coalesce(func.sum(models.FlightTurnPoint.landing_duration), 0).label("landing_duration")
).join(models.Flight.turn_points, isouter=True)
.group_by(models.Flight.id)
.filter(models.Flight.id.in_(ids))
+14 -5
View File
@@ -98,7 +98,7 @@ flight_by_poi_dataloader = DataLoader(
models.Flight,
relationship_column=models.PointOfInterest.id,
order_by=[models.Flight.takeoff_datetime.desc()],
extra_join=[models.Flight.track, models.PointOfInterest]
extra_join=[models.Flight.turn_points, models.PointOfInterest]
).load,
cache=False
)
@@ -155,11 +155,20 @@ poi_photos_dataloader = DataLoader(
).load,
cache=False
)
flight_track_dataloader = DataLoader(
flight_turn_points_dataloader = DataLoader(
load_fn=MultiModelsDataloader(
models.FlightTrack,
relationship_column=models.FlightTrack.flight_id,
order_by=[models.FlightTrack.order]
models.FlightTurnPoint,
relationship_column=models.FlightTurnPoint.flight_id,
order_by=[models.FlightTurnPoint.order]
).load,
cache=False
)
track_points_dataloder = DataLoader(
load_fn=MultiModelsDataloader(
models.TrackPoint,
relationship_column=models.TrackPoint.track_id,
order_by=[models.TrackPoint.timestamp, models.TrackPoint.id]
).load,
cache=False
)
@@ -15,6 +15,7 @@ aircraft_dataloader = create_dataloader(models.Aircraft)
event_dataloader = create_dataloader(models.Event)
organizations_dataloader = create_dataloader(models.Organization)
airport_weather_info_loader = create_dataloader(models.WeatherInfo)
track_dataloader = create_dataloader(models.Track)
poi_dataloader = create_dataloader(models.PointOfInterest)
poi_type_dataloader = create_dataloader(models.PointOfInterestType)
flight_dataloader = create_dataloader(models.Flight)
@@ -58,8 +58,8 @@ class FlightQueryResolver(BaseQueryResolver):
if kwargs.get("point_of_interest_id"):
query = (
query.join(models.Flight.track)
.filter(models.FlightTrack.point_of_interest_id == kwargs["point_of_interest_id"])
query.join(models.Flight.turn_points)
.filter(models.FlightTurnPoint.point_of_interest_id == kwargs["point_of_interest_id"])
)
if kwargs.get('username'):
@@ -252,7 +252,7 @@ async def handle_upload_gpx(gpx_track: Upload, context, original_gpx_filename: O
async def handle_track_edit(db: AsyncSession, flight_id: int, track: List[TrackItemInput], user_id: int):
await db.execute(delete(models.FlightTrack).filter(models.FlightTrack.flight_id == flight_id))
await db.execute(delete(models.FlightTurnPoint).filter(models.FlightTurnPoint.flight_id == flight_id))
order = 0
for item in track:
@@ -280,7 +280,7 @@ async def handle_track_edit(db: AsyncSession, flight_id: int, track: List[TrackI
}
)
await models.FlightTrack.create(
await models.FlightTurnPoint.create(
db,
data={
"flight_id": flight_id,
+22 -46
View File
@@ -1,7 +1,5 @@
from __future__ import annotations
import math
from datetime import datetime
from typing import Optional, List
import strawberry
from database import models
@@ -10,17 +8,17 @@ from utils.gps import get_bearing, get_distance
from external.gpx_parser import GPXParser
from graphql_schema.dataloaders.flight_duration import flight_duration_dataloader
from graphql_schema.dataloaders.multi_models import (
poi_photos_dataloader, flight_by_poi_dataloader, flight_copilots_dataloader, flight_track_dataloader,
poi_photos_dataloader, flight_by_poi_dataloader, flight_copilots_dataloader, flight_turn_points_dataloader,
photos_dataloader, flights_by_aircraft_dataloader, users_in_organization_dataloader,
aircrafts_from_organization_dataloader, user_organizations_dataloader, flights_by_event_dataloader,
flights_by_copilot_dataloader, public_flights_by_event_dataloader, public_flights_by_copilot_dataloader,
photo_copilots_dataloader, photos_aircraft_dataloader, copilots_in_photo_dataloader, flight_plan_markers_dataloader,
reporting_points_dataloader, flight_plan_copilots_dataloader, runways_dataloader, frequencies_dataloader
reporting_points_dataloader, flight_plan_copilots_dataloader, runways_dataloader, frequencies_dataloader, track_points_dataloder
)
from graphql_schema.dataloaders.single_model import (
poi_dataloader, poi_type_dataloader, event_dataloader, aircraft_dataloader, airport_dataloader,
airport_weather_info_loader, organizations_dataloader, flight_dataloader, photo_adjustment_dataloader,
photo_dataloader, user_dataloader
photo_dataloader, user_dataloader, track_dataloader
)
from graphql_schema.permissions import IsAuthenticated
from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_type
@@ -33,18 +31,6 @@ class Point:
lng: float
@strawberry.type
class GPXTrack:
coordinates: List[Point]
speed: List[float]
altitude: List[float]
magnetic_variation: List[float]
terrain_elevation: List[float]
time: List[datetime]
max_speed: float
avg_speed: float
max_altitude: float
avg_altitude: float
@strawberry_sqlalchemy_type(models.ReportingPoint)
@@ -88,8 +74,8 @@ class Airspace:
)
@strawberry_sqlalchemy_type(models.FlightTrack)
class FlightTrack:
@strawberry_sqlalchemy_type(models.FlightTurnPoint)
class FlightTurnPoint:
point_of_interest: Optional[PointOfInterest] = strawberry.field(
resolver=lambda root: poi_dataloader.load(root.point_of_interest_id)
)
@@ -133,6 +119,20 @@ class Photo:
)
@strawberry_sqlalchemy_type(models.TrackPoint)
class TrackPoint:
coordinates: Point = strawberry.field(resolver=lambda root: Point(lat=root.gps_latitude, lng=root.gps_longitude))
@strawberry_sqlalchemy_type(models.Track, exclude_fields=['bounds'])
class Track:
bounds: list[tuple[float, float]]
map_bounds: list[Point] = strawberry.field(
resolver=lambda root: [Point(lat=point[1], lng=point[0]) for point in root.bounds]
)
points: list[TrackPoint] = strawberry.field(resolver=lambda root: track_points_dataloder.load(root.id))
@strawberry_sqlalchemy_type(models.Flight)
class Flight:
def __init__(self, **kwargs):
@@ -141,28 +141,6 @@ class Flight:
for key, value in kwargs.items():
setattr(self, key, value)
async def load_gpx_track(root):
if not root.gpx_track_filename:
return None
try:
gpx_parser = GPXParser(f"{FLIGHT_GPX_TRACK_PATH}/{root.gpx_track_filename}")
except OSError:
return None
return GPXTrack(
coordinates=[Point(**point) for point in await gpx_parser.get_coordinates()],
speed=await gpx_parser.get_speed(),
altitude=await gpx_parser.get_altitude(),
terrain_elevation=await gpx_parser.get_terrain_elevation(),
time=await gpx_parser.get_times(),
max_speed=await gpx_parser.get_max_speed(),
avg_speed=await gpx_parser.get_avg_speed(),
max_altitude=await gpx_parser.get_max_altitude(),
avg_altitude=await gpx_parser.get_avg_altitude(),
magnetic_variation=await gpx_parser.get_magnetic_variation(),
)
@authenticated_user_only(raise_when_unauthorized=False, return_value_unauthorized=[])
async def load_copilots(root):
return await flight_copilots_dataloader.load(root.id)
@@ -182,7 +160,7 @@ class Flight:
resolver=lambda root: airport_dataloader.load(root.landing_airport_id)
)
title_photo: Optional[Photo] = strawberry.field(resolver=lambda root: photo_dataloader.load(root.title_photo_id))
track: List[FlightTrack] = strawberry.field(resolver=lambda root: flight_track_dataloader.load(root.id))
turn_points: List[FlightTurnPoint] = strawberry.field(resolver=lambda root: flight_turn_points_dataloader.load(root.id))
takeoff_weather_info: Optional[WeatherInfo] = strawberry.field(
resolver=lambda root: airport_weather_info_loader.load(root.takeoff_weather_info_id)
)
@@ -190,10 +168,8 @@ class Flight:
resolver=lambda root: airport_weather_info_loader.load(root.landing_weather_info_id)
)
photos: List[Photo] = strawberry.field(resolver=lambda root: photos_dataloader.load(root.id))
gpx_track: Optional[GPXTrack] = strawberry.field(resolver=load_gpx_track)
duration_min_calculated: int = strawberry.field(
resolver=lambda root: flight_duration_dataloader.load(root.id)
)
track: Optional[Track] = strawberry.field(resolver=lambda root: track_dataloader.load(root.track_id))
duration_min_calculated: int = strawberry.field(resolver=lambda root: flight_duration_dataloader.load(root.id))
social_image_url: Optional[str] = strawberry.field(
resolver=lambda root: get_public_url(f'photos/{root.id}/title_photo.jpg')
)