149 lines
4.0 KiB
Vue
149 lines
4.0 KiB
Vue
<script setup>
|
|
import MapWithMarkers from "components/map/MapWithMarkers.vue";
|
|
import {computed, reactive, ref} from "vue";
|
|
import {Line} from "vue-chartjs"
|
|
import {useFlightPlanUtils} from "src/composables/flightPlan";
|
|
|
|
const props = defineProps({
|
|
flight: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
flightPlan: {
|
|
type: Object,
|
|
required: false,
|
|
},
|
|
photos: {
|
|
type: Array,
|
|
required: false,
|
|
}
|
|
})
|
|
|
|
|
|
const mapPhotos = computed(() => props.photos.filter(photo => photo.gpsLatitude && photo.gpsLongitude));
|
|
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 pointsOfInterests = computed(() => mapMarkers
|
|
.filter(marker => marker && marker.gpsLatitude && marker.gpsLongitude)
|
|
.map(
|
|
marker => ({label: marker.name, position: {lat: marker.gpsLatitude, lng: marker.gpsLongitude}})
|
|
));
|
|
|
|
// Tuu bylo reactive()
|
|
const flightTrack = props.flight.track ? props.flight.track.points : null;
|
|
|
|
const displayMap = computed(() => {
|
|
return (
|
|
!!flightTrack ||
|
|
mapPhotos.value.length > 0 ||
|
|
poisWithGPS.value.length > 0 ||
|
|
props.flight.landingAirport.id !== props.flight.takeoffAirport.id
|
|
)
|
|
});
|
|
|
|
let chartSpeedData, chartAltitudeData = null;
|
|
if (flightTrack) {
|
|
|
|
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);
|
|
return datetime.getHours() + ":" + datetime.getMinutes();
|
|
});
|
|
chartSpeedData = {
|
|
labels: chartLabels,
|
|
datasets: [{
|
|
backgroundColor: "#38bd3e",
|
|
borderColor: "#38bd3e",
|
|
label: "Rychlost (km/h)",
|
|
data: speed,
|
|
pointRadius: 1,
|
|
}]
|
|
};
|
|
|
|
chartAltitudeData = {
|
|
labels: chartLabels,
|
|
datasets: [{
|
|
backgroundColor: "#9ae3ff",
|
|
borderColor: "#9ae3ff",
|
|
label: "Nadmořská výška letu (m)",
|
|
data: altitude,
|
|
pointRadius: 1,
|
|
}]
|
|
};
|
|
|
|
if (terrainElevation.length > 0) {
|
|
chartAltitudeData.datasets.push(
|
|
{
|
|
backgroundColor: "rgba(148,94,40,0.7)",
|
|
borderColor: "#945e28",
|
|
label: "Nadmořská výška země (m)",
|
|
data: terrainElevation,
|
|
fill: true,
|
|
pointRadius: 1,
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
const currentPositionMarker = ref(null);
|
|
const drawCurrentPositionMarker = (e) => {
|
|
const res = e.chart.getElementsAtEventForMode(e, 'nearest', {intersect: false});
|
|
if (res.length === 0) {
|
|
currentPositionMarker.value = null;
|
|
return;
|
|
}
|
|
const idx = res[0].index;
|
|
currentPositionMarker.value = props.flight.track.points[idx].coordinates;
|
|
}
|
|
|
|
const chartOptions = {
|
|
plugins: {
|
|
tooltip: {
|
|
mode: 'index',
|
|
intersect: false,
|
|
}
|
|
},
|
|
onClick: drawCurrentPositionMarker,
|
|
onHover: drawCurrentPositionMarker,
|
|
}
|
|
|
|
const {getMarkersFrom} = useFlightPlanUtils();
|
|
const showPlanTrack = ref(true);
|
|
const tracks = computed(() => {
|
|
const items = [];
|
|
if (props.flight.track) {
|
|
items.push(props.flight.track.points.map(m => m.coordinates))
|
|
}
|
|
if (showPlanTrack.value && props.flightPlan) {
|
|
items.push(getMarkersFrom(props.flightPlan).map(m => ({lat: m.gpsLatitude, lng: m.gpsLongitude})));
|
|
}
|
|
return items;
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<q-no-ssr>
|
|
<q-intersection>
|
|
<q-checkbox v-model="showPlanTrack" label="Zobrazovat plán?" v-if="flightPlan" />
|
|
|
|
<MapWithMarkers
|
|
v-if="displayMap"
|
|
style="width: 100%; height: 500px;"
|
|
:tracks="tracks"
|
|
:markers="pointsOfInterests"
|
|
:highlight-position="currentPositionMarker"
|
|
:photos="mapPhotos"
|
|
v-bind="$attrs"
|
|
/>
|
|
|
|
<Line v-if="flightTrack" :data="chartSpeedData" :options="chartOptions"/>
|
|
<Line v-if="flightTrack" :data="chartAltitudeData" :options="chartOptions"/>
|
|
</q-intersection>
|
|
</q-no-ssr>
|
|
</template>
|