Vykreslovat trasu na zaklade dat z z db

This commit is contained in:
Michal Kváček
2024-07-25 19:51:15 +02:00
parent 88a760846c
commit e8dc51a80d
10 changed files with 58 additions and 46 deletions
+2 -2
View File
@@ -36,8 +36,8 @@ useEventsStore().fetchFlightsTracks({
for (const flightTrack of data.flights) { for (const flightTrack of data.flights) {
totalTime.value += flightTrack.durationMinCalculated; totalTime.value += flightTrack.durationMinCalculated;
if (flightTrack.gpxTrack) { if (flightTrack.track) {
tracks.value.push(flightTrack.gpxTrack.coordinates); tracks.value.push(flightTrack.track.coordinates);
} }
} }
}); });
+1 -1
View File
@@ -82,7 +82,7 @@ const props = defineProps({
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-for="poi in flight.track" :key="poi.id"> <q-item v-for="poi in flight.turnPoints" :key="poi.id">
<q-item-section avatar> <q-item-section avatar>
<q-icon name="place" v-if="poi.pointOfInterest"/> <q-icon name="place" v-if="poi.pointOfInterest"/>
<q-icon name="local_airport" v-if="poi.airport"/> <q-icon name="local_airport" v-if="poi.airport"/>
+23 -14
View File
@@ -21,7 +21,7 @@ const props = defineProps({
const mapPhotos = computed(() => props.photos.filter(photo => photo.gpsLatitude && photo.gpsLongitude)); const mapPhotos = computed(() => props.photos.filter(photo => photo.gpsLatitude && photo.gpsLongitude));
const poisWithGPS = computed(() => props.flight.track.map(poi => poi.pointOfInterest || poi.airport)); const poisWithGPS = computed(() => props.flight.turnPoints.map(poi => poi.pointOfInterest || poi.airport));
const mapMarkers = [props.flight.takeoffAirport].concat(poisWithGPS.value).concat([props.flight.landingAirport]); const mapMarkers = [props.flight.takeoffAirport].concat(poisWithGPS.value).concat([props.flight.landingAirport]);
const pointsOfInterests = computed(() => mapMarkers const pointsOfInterests = computed(() => mapMarkers
@@ -30,10 +30,12 @@ const pointsOfInterests = computed(() => mapMarkers
marker => ({label: marker.name, position: {lat: marker.gpsLatitude, lng: marker.gpsLongitude}}) marker => ({label: marker.name, position: {lat: marker.gpsLatitude, lng: marker.gpsLongitude}})
)); ));
const gpxTrack = props.flight.gpxTrack ? reactive(props.flight.gpxTrack) : null; // Tuu bylo reactive()
const flightTrack = props.flight.track ? props.flight.track.points : null;
const displayMap = computed(() => { const displayMap = computed(() => {
return ( return (
!!gpxTrack || !!flightTrack ||
mapPhotos.value.length > 0 || mapPhotos.value.length > 0 ||
poisWithGPS.value.length > 0 || poisWithGPS.value.length > 0 ||
props.flight.landingAirport.id !== props.flight.takeoffAirport.id props.flight.landingAirport.id !== props.flight.takeoffAirport.id
@@ -41,8 +43,14 @@ const displayMap = computed(() => {
}); });
let chartSpeedData, chartAltitudeData = null; let chartSpeedData, chartAltitudeData = null;
if (gpxTrack) { if (flightTrack) {
const chartLabels = gpxTrack.time.map(t => {
const timestamp = flightTrack.map(i => i.timestamp);
const speed = flightTrack.map(i => i.speed);
const altitude = flightTrack.map(i => i.altitude);
const terrainElevation = flightTrack.map(i => i.terrainElevation || 0);
const chartLabels = timestamp.map(t => {
const datetime = new Date(t); const datetime = new Date(t);
return datetime.getHours() + ":" + datetime.getMinutes(); return datetime.getHours() + ":" + datetime.getMinutes();
}); });
@@ -52,7 +60,7 @@ if (gpxTrack) {
backgroundColor: "#38bd3e", backgroundColor: "#38bd3e",
borderColor: "#38bd3e", borderColor: "#38bd3e",
label: "Rychlost (km/h)", label: "Rychlost (km/h)",
data: gpxTrack.speed, data: speed,
pointRadius: 1, pointRadius: 1,
}] }]
}; };
@@ -63,18 +71,18 @@ if (gpxTrack) {
backgroundColor: "#9ae3ff", backgroundColor: "#9ae3ff",
borderColor: "#9ae3ff", borderColor: "#9ae3ff",
label: "Nadmořská výška letu (m)", label: "Nadmořská výška letu (m)",
data: gpxTrack.altitude, data: altitude,
pointRadius: 1, pointRadius: 1,
}] }]
}; };
if (gpxTrack.terrainElevation.length > 0) { if (terrainElevation.length > 0) {
chartAltitudeData.datasets.push( chartAltitudeData.datasets.push(
{ {
backgroundColor: "rgba(148,94,40,0.7)", backgroundColor: "rgba(148,94,40,0.7)",
borderColor: "#945e28", borderColor: "#945e28",
label: "Nadmořská výška země (m)", label: "Nadmořská výška země (m)",
data: gpxTrack.terrainElevation, data: terrainElevation,
fill: true, fill: true,
pointRadius: 1, pointRadius: 1,
}); });
@@ -90,7 +98,7 @@ const drawCurrentPositionMarker = (e) => {
return; return;
} }
const idx = res[0].index; const idx = res[0].index;
currentPositionMarker.value = props.flight.gpxTrack.coordinates[idx]; currentPositionMarker.value = props.flight.track.points[idx].coordinates;
} }
const chartOptions = { const chartOptions = {
@@ -108,8 +116,8 @@ const {getMarkersFrom} = useFlightPlanUtils();
const showPlanTrack = ref(true); const showPlanTrack = ref(true);
const tracks = computed(() => { const tracks = computed(() => {
const items = []; const items = [];
if (props.flight.gpxTrack) { if (props.flight.track) {
items.push(props.flight.gpxTrack.coordinates) items.push(props.flight.track.points.map(m => m.coordinates))
} }
if (showPlanTrack.value && props.flightPlan) { if (showPlanTrack.value && props.flightPlan) {
items.push(getMarkersFrom(props.flightPlan).map(m => ({lat: m.gpsLatitude, lng: m.gpsLongitude}))); items.push(getMarkersFrom(props.flightPlan).map(m => ({lat: m.gpsLatitude, lng: m.gpsLongitude})));
@@ -122,6 +130,7 @@ const tracks = computed(() => {
<q-no-ssr> <q-no-ssr>
<q-intersection> <q-intersection>
<q-checkbox v-model="showPlanTrack" label="Zobrazovat plán?" v-if="flightPlan" /> <q-checkbox v-model="showPlanTrack" label="Zobrazovat plán?" v-if="flightPlan" />
<MapWithMarkers <MapWithMarkers
v-if="displayMap" v-if="displayMap"
style="width: 100%; height: 500px;" style="width: 100%; height: 500px;"
@@ -132,8 +141,8 @@ const tracks = computed(() => {
v-bind="$attrs" v-bind="$attrs"
/> />
<Line v-if="gpxTrack" :data="chartSpeedData" :options="chartOptions"/> <Line v-if="flightTrack" :data="chartSpeedData" :options="chartOptions"/>
<Line v-if="gpxTrack" :data="chartAltitudeData" :options="chartOptions"/> <Line v-if="flightTrack" :data="chartAltitudeData" :options="chartOptions"/>
</q-intersection> </q-intersection>
</q-no-ssr> </q-no-ssr>
</template> </template>
@@ -51,7 +51,7 @@ watch(poi, (newVal) => {
} }
}); });
watch(() => props.flight.track, (newVal) => { watch(() => props.flight.turnPoints, (newVal) => {
formData.track = []; formData.track = [];
for (const i in newVal) { for (const i in newVal) {
const trackInfo = newVal[i]; const trackInfo = newVal[i];
@@ -76,7 +76,7 @@ watch(() => props.flight.track, (newVal) => {
<template> <template>
<FormWrapper v-model="formData"> <FormWrapper v-model="formData">
<q-banner class="bg-green text-white" v-if="flight.gpxTrack"> <q-banner class="bg-green text-white" v-if="flight.track">
<q-icon name="check"/> <q-icon name="check"/>
Trasa nahrána Trasa nahrána
</q-banner> </q-banner>
+11 -15
View File
@@ -5,12 +5,6 @@ import {computed} from "vue";
const props = defineProps({ const props = defineProps({
gpxTrack: {
type: Object,
required: false,
default: () => {
}
},
tracks: { tracks: {
type: Array, type: Array,
required: false, required: false,
@@ -29,6 +23,11 @@ const props = defineProps({
type: Array, type: Array,
required: false, required: false,
default: () => [] default: () => []
},
bounds: {
type: Array,
required: false,
default: () => []
} }
}) })
@@ -36,14 +35,15 @@ const bounds = computed(() => {
const photosTransformed = props.photos.map(p => ({position: {lat: p.gpsLatitude, lng: p.gpsLongitude}})); const photosTransformed = props.photos.map(p => ({position: {lat: p.gpsLatitude, lng: p.gpsLongitude}}));
const coordinates = [ const coordinates = [
...[...props.markers, ...photosTransformed].filter(i => !!i.position).map(i => i.position), ...[...props.markers, ...photosTransformed].filter(i => !!i.position).map(i => i.position),
...(props.gpxTrack || []),
...(props.tracks || []).flat() ...(props.tracks || []).flat()
]; ];
const minLat = Math.min(...coordinates.map(i => i.lat)); const latitudes = coordinates.filter(i => i && i.lat).map(i => i.lat);
const maxLat = Math.max(...coordinates.map(i => i.lat)); const longitudes = coordinates.filter(i => i && i.lng).map(i => i.lng);
const minLng = Math.min(...coordinates.map(i => i.lng)); const minLat = Math.min(...latitudes);
const maxLng = Math.max(...coordinates.map(i => i.lng)); const maxLat = Math.max(...latitudes);
const minLng = Math.min(...longitudes);
const maxLng = Math.max(...longitudes);
return [ return [
{lat: minLat, lng: minLng}, {lat: minLat, lng: minLng},
@@ -84,10 +84,6 @@ const getColor = (i) => {
</InfoWindow> </InfoWindow>
</Marker> </Marker>
<template v-if="gpxTrack && gpxTrack.length > 0">
<Polyline :options="{path: gpxTrack, geodesic: true, strokeColor: getColor(0), strokeOpacity: 0.5, strokeWeight: 5}"/>
</template>
<template v-if="tracks && tracks.length > 0"> <template v-if="tracks && tracks.length > 0">
<template v-for="(track, i) in tracks" :key="track"> <template v-for="(track, i) in tracks" :key="track">
<Polyline :options="{path: track, geodesic: true, strokeColor: getColor(i), strokeOpacity: 0.5, strokeWeight: 5}"/> <Polyline :options="{path: track, geodesic: true, strokeColor: getColor(i), strokeOpacity: 0.5, strokeWeight: 5}"/>
+1 -1
View File
@@ -5,7 +5,7 @@ export const flightName = (flight) => {
if (flight.name !== '') { if (flight.name !== '') {
return `${flight.name} (${date})` return `${flight.name} (${date})`
} else { } else {
const track = flight.track ? flight.track.map(t => t.pointOfInterest?.name || t.airport?.icaoCode) : []; const track = flight.turnPoints ? flight.turnPoints.map(t => t.pointOfInterest?.name || t.airport?.icaoCode) : [];
const trackStr = track.length > 0 ? ` - ${track.join(" - ")} - ` : ' - '; const trackStr = track.length > 0 ? ` - ${track.join(" - ")} - ` : ' - ';
return `${flight.takeoffAirport?.icaoCode || '???'} ${trackStr} ${flight.landingAirport?.icaoCode || "???"} (${date})`; return `${flight.takeoffAirport?.icaoCode || '???'} ${trackStr} ${flight.landingAirport?.icaoCode || "???"} (${date})`;
+15 -8
View File
@@ -61,23 +61,30 @@ fragment flightFullInfo on Flight {
name name
} }
gpxTrack { track {
coordinates { points {
coordinates {
lat
lng
}
timestamp
magneticVariation
speed
altitude
terrainElevation
}
mapBounds {
lat lat
lng lng
} }
time
magneticVariation
speed
maxSpeed maxSpeed
avgSpeed avgSpeed
altitude
terrainElevation
maxAltitude maxAltitude
avgAltitude avgAltitude
} }
track { turnPoints {
pointOfInterest { pointOfInterest {
...pointOfInterestFullInfo ...pointOfInterestFullInfo
} }
+1 -1
View File
@@ -17,7 +17,7 @@ fragment flightListInfo on Flight {
url url
} }
track { turnPoints {
pointOfInterest { pointOfInterest {
id id
name name
+1 -1
View File
@@ -25,7 +25,7 @@ query eventsFlightsTracks($eventId: Int, $eventUrlSlug: String, $onlyPublic: Boo
event(id: $eventId, urlSlug: $eventUrlSlug, public: $onlyPublic) { event(id: $eventId, urlSlug: $eventUrlSlug, public: $onlyPublic) {
flights(onlyPublic: $onlyPublic) { flights(onlyPublic: $onlyPublic) {
durationMinCalculated durationMinCalculated
gpxTrack { tracks {
coordinates { coordinates {
lat lat
lng lng
@@ -149,7 +149,7 @@ const togglePublicVisibility = (variables) => toggleVisibility({
label="Upravit trasu" label="Upravit trasu"
/> />
<BasicInfoBanner <BasicInfoBanner
v-if="flight.track.length === 0 && !flight.gpxTrack" v-if="flight.turnPoints.length === 0 && !flight.track"
:route-add="{name: 'flightEdit', params: {id: flightId, step: 'track'}}" :route-add="{name: 'flightEdit', params: {id: flightId, step: 'track'}}"
> >
Nemáš nastavenou žádnou trasu. Nemáš nastavenou žádnou trasu.