Zobrazovani informaci o RWY, vylepseni zobrazeni vysek
This commit is contained in:
@@ -21,6 +21,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const getLimitFormatted = (limit, unit) => {
|
||||
if (parseInt(limit) === 0) return 'GND';
|
||||
return `${limit} ${unit}`
|
||||
}
|
||||
|
||||
|
||||
@@ -58,12 +58,16 @@ const addMarker = async (point) => {
|
||||
const insertAt = Math.min(markers.value.length, props.insertPosition);
|
||||
|
||||
markers.value.splice(insertAt, 0, markerObject({...point}));
|
||||
// infoWindow.value = infoWindowObject({active: false});
|
||||
|
||||
emits("markers-changed", markers.value);
|
||||
emits("change-insert-position", insertAt + 1);
|
||||
}
|
||||
|
||||
const removeMarker = (idx) => {
|
||||
markers.value.splice(idx, 1);
|
||||
emits("markers-changed", markers.value);
|
||||
}
|
||||
|
||||
const {searchPlaceName} = useGeocode();
|
||||
const handleMarkerMove = async (idx, event) => {
|
||||
markers.value[idx].name = await searchPlaceName(event.lat(), event.lng());
|
||||
@@ -89,6 +93,7 @@ const handleMarkerMove = async (idx, event) => {
|
||||
:show-layer-controls="true"
|
||||
:allow-add-marker="true"
|
||||
@add-to-route="addMarker"
|
||||
@remove-from-route="removeMarker"
|
||||
|
||||
>
|
||||
<template v-for="poi in pointsOfInterest" :key="poi.name">
|
||||
|
||||
@@ -59,12 +59,15 @@ const totalTime = computed(() => {
|
||||
<q-btn
|
||||
@click='emits("fullscreen-toggle")'
|
||||
size="sm"
|
||||
round
|
||||
:icon="isFullscreen ? 'mdi-fullscreen-exit' : 'mdi-fullscreen'"
|
||||
/>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
||||
{{ insertPosition }} {{ flightPlan.track.length }}
|
||||
|
||||
<q-scroll-area style="height: 50vh">
|
||||
<template v-for="(segment, i) in props.flightPlan.track" :key="segment">
|
||||
<q-item dense>
|
||||
@@ -81,7 +84,6 @@ const totalTime = computed(() => {
|
||||
icon="add"
|
||||
size="sm"
|
||||
class="q-ml-lg q-mb-sm"
|
||||
:round="insertPosition !== i+1"
|
||||
:color="insertPosition === i+1 ? 'primary' : 'grey'"
|
||||
>
|
||||
<template v-if="insertPosition === i+1">Přidávám sem</template>
|
||||
@@ -90,7 +92,6 @@ const totalTime = computed(() => {
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
||||
|
||||
<q-item dense v-if="segment.to && i === props.flightPlan.track.length - 1">
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
@@ -99,21 +100,22 @@ const totalTime = computed(() => {
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
<q-item>
|
||||
<q-item-section v-if="flightPlan.track.length">
|
||||
<div>
|
||||
<q-btn
|
||||
@click="emits('change-insert-position', flightPlan.track.length + 1)"
|
||||
icon="add"
|
||||
size="sm"
|
||||
:color="insertPosition === flightPlan.track.length + 1? 'primary' : 'grey'"
|
||||
>
|
||||
<template v-if="insertPosition === flightPlan.track.length + 1">Přidávám na konec</template>
|
||||
</q-btn>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-scroll-area>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<div>
|
||||
<q-btn
|
||||
@click="emits('change-insert-position', flightPlan.track.length + 1)"
|
||||
icon="add"
|
||||
size="sm"
|
||||
:color="insertPosition === flightPlan.track.length + 1? 'primary' : 'grey'"
|
||||
>
|
||||
<template v-if="insertPosition === flightPlan.track.length + 1">Přidávám na konec</template>
|
||||
</q-btn>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<template v-if="totalDistance">
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import {InfoWindow} from "vue3-google-map";
|
||||
import {useFlightPlanUtils} from "src/composables/flightPlan";
|
||||
import {useGeocode} from "src/composables/geocoding";
|
||||
import {ref, watch} from "vue";
|
||||
import {computed, ref, watch} from "vue";
|
||||
import {useAirspaceColors} from "src/composables/airspaces";
|
||||
import AltitudeLimit from "components/AltitudeLimit.vue";
|
||||
|
||||
@@ -23,7 +23,7 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
|
||||
const emits = defineEmits(["add-to-route", "highlight-airspace", "close"])
|
||||
const emits = defineEmits(["add-to-route", "remove-from-route", "highlight-airspace", "close"])
|
||||
|
||||
const {getIcon} = useFlightPlanUtils();
|
||||
const {searchPlaceName} = useGeocode()
|
||||
@@ -38,7 +38,7 @@ watch(() => props.infoWindow.position, async () => {
|
||||
}
|
||||
}, {immediate: true, deep: true});
|
||||
|
||||
const addPoint = async () => {
|
||||
const addPoint = () => {
|
||||
let type = "mapPoint";
|
||||
if (props.infoWindow.poi) {
|
||||
type = "poi";
|
||||
@@ -52,12 +52,39 @@ const addPoint = async () => {
|
||||
gpsLongitude: props.infoWindow.position.lng
|
||||
}
|
||||
emits("add-to-route", point)
|
||||
emits("close");
|
||||
}
|
||||
|
||||
const removePoint = (marker) => {
|
||||
emits("remove-from-route", marker);
|
||||
emits("close");
|
||||
}
|
||||
|
||||
const {getColorByType} = useAirspaceColors();
|
||||
const highlightAirspace = (airspace) => {
|
||||
emits('highlight-airspace', airspace.name)
|
||||
}
|
||||
|
||||
const runways = computed(() => {
|
||||
const runwayPairs = {};
|
||||
|
||||
for (const runway of props.infoWindow.airport.runways) {
|
||||
runwayPairs[runway.designator] = runway;
|
||||
}
|
||||
|
||||
return runwayPairs;
|
||||
});
|
||||
|
||||
const runwaySurfaceName = (surface) => {
|
||||
const surfaceMap = {
|
||||
grass: "tráva",
|
||||
concrete: "beton",
|
||||
asphalt: "asfalt"
|
||||
}
|
||||
return surfaceMap[surface] || 'jiné'
|
||||
}
|
||||
|
||||
const openedTab = ref("info");
|
||||
</script>
|
||||
|
||||
|
||||
@@ -66,56 +93,113 @@ const highlightAirspace = (airspace) => {
|
||||
@close="emits('close')"
|
||||
:options="{position: infoWindow.position}"
|
||||
>
|
||||
<div class="text-h5">{{ title }}</div>
|
||||
|
||||
<div v-if="infoWindow.marker">
|
||||
<q-tabs v-model="openedTab">
|
||||
<q-tab name="info">{{ title }}</q-tab>
|
||||
<q-tab name="airspaces" v-if="infoWindow.airspaces?.length">Prostory</q-tab>
|
||||
</q-tabs>
|
||||
<q-tab-panels v-model="openedTab">
|
||||
<q-tab-panel name="info">
|
||||
<div v-if="infoWindow.airport">
|
||||
Elevace: {{ infoWindow.airport.elevation }} m
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<q-list dense>
|
||||
<q-item dense v-for="runway in runways" :key="runway">
|
||||
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
<strong>{{ runway.designator }}</strong> ({{ runwaySurfaceName(runway.surface) }})
|
||||
</q-item-label>
|
||||
<q-item-label caption>
|
||||
{{ runway.heading }}°, {{ runway.width }} × {{ runway.length }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item dense v-for="frequency in infoWindow.airport.frequencies" :key="frequency">
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
<strong>{{ frequency.name }}</strong>
|
||||
</q-item-label>
|
||||
<q-item-label caption>
|
||||
{{ frequency.frequency }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-if="infoWindow.marker">
|
||||
<span class="text-h6">
|
||||
<q-icon :name="getIcon(infoWindow.marker.type)"/>
|
||||
{{ infoWindow.marker.name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="infoWindow.poi">
|
||||
<q-img :src="infoWindow.poi.titlePhoto.thumbnailUrl" width="300px" v-if="infoWindow.poi.titlePhoto"/>
|
||||
</div>
|
||||
<div v-if="infoWindow.poi">
|
||||
<q-img :src="infoWindow.poi.titlePhoto.thumbnailUrl" width="300px" v-if="infoWindow.poi.titlePhoto"/>
|
||||
</div>
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="airspaces" v-if="infoWindow.airspaces?.length">
|
||||
<q-list>
|
||||
<q-item-label v-for="airspace in infoWindow.airspaces" :key="airspace.name">
|
||||
<q-avatar size="16px" class="q-mx-sm" :style="`border: solid 1px; background: ${getColorByType(airspace.type)}`"/>
|
||||
|
||||
<template v-if="infoWindow.airspaces?.length">
|
||||
<span class="text-h6">Prostory</span>
|
||||
<q-list>
|
||||
<q-item-label v-for="airspace in infoWindow.airspaces" :key="airspace.name">
|
||||
<q-avatar size="16px" class="q-mx-sm" :style="`border: solid 1px; background: ${getColorByType(airspace.type)}`"/>
|
||||
<strong>
|
||||
{{ airspace.name }}
|
||||
</strong>
|
||||
|
||||
<strong>
|
||||
{{ airspace.name }}
|
||||
</strong>
|
||||
<AltitudeLimit
|
||||
class="q-mx-md"
|
||||
:upper-limit="airspace.upperLimit"
|
||||
:upper-limit-unit="airspace.upperAltUnit"
|
||||
:lower-limit="airspace.lowerLimit"
|
||||
:lower-limit-unit="airspace.lowerAltUnit"
|
||||
/>
|
||||
|
||||
<AltitudeLimit
|
||||
class="q-mx-md"
|
||||
:upper-limit="airspace.upperLimit"
|
||||
:upper-limit-unit="airspace.upperAltUnit"
|
||||
:lower-limit="airspace.lowerLimit"
|
||||
:lower-limit-unit="airspace.lowerAltUnit"
|
||||
/>
|
||||
<q-btn
|
||||
v-if="airspace.type !== 'FIR'"
|
||||
color="white"
|
||||
:text-color="props.highlightedAirspaces.includes(airspace.name) ? 'primary' : 'grey-6'"
|
||||
size="x-small"
|
||||
round
|
||||
text
|
||||
icon="mdi-eye"
|
||||
@click="highlightAirspace(airspace)"
|
||||
/>
|
||||
</q-item-label>
|
||||
</q-list>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
|
||||
<q-btn
|
||||
v-if="airspace.type !== 'FIR'"
|
||||
color="white"
|
||||
:text-color="props.highlightedAirspaces.includes(airspace.name) ? 'primary' : 'grey-6'"
|
||||
size="x-small"
|
||||
round
|
||||
text
|
||||
icon="mdi-eye"
|
||||
@click="highlightAirspace(airspace)"
|
||||
/>
|
||||
</q-item-label>
|
||||
</q-list>
|
||||
<template v-if="showActions">
|
||||
<q-btn
|
||||
v-if="infoWindow.marker"
|
||||
class="q-mt-lg full-width"
|
||||
color="warning"
|
||||
@click="removePoint(infoWindow.marker.position)"
|
||||
>
|
||||
Odebrat z trasy
|
||||
</q-btn>
|
||||
<q-btn
|
||||
v-else
|
||||
class="full-width q-mt-lg"
|
||||
color="secondary"
|
||||
@click="addPoint()"
|
||||
>
|
||||
Přidat bod do trasy
|
||||
</q-btn>
|
||||
</template>
|
||||
<q-btn
|
||||
v-if="showActions"
|
||||
class="q-mt-lg"
|
||||
color="secondary"
|
||||
@click="addPoint()">
|
||||
Přidat bod do trasy
|
||||
</q-btn>
|
||||
|
||||
|
||||
</InfoWindow>
|
||||
</template>
|
||||
|
||||
@@ -38,7 +38,7 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
|
||||
const emits = defineEmits(["map-click", "add-to-route"]);
|
||||
const emits = defineEmits(["map-click", "add-to-route", "remove-from-route"]);
|
||||
|
||||
const key = process.env.GOOGLE_MAPS_API_KEY;
|
||||
|
||||
@@ -89,17 +89,20 @@ const airspaces = computed(() => {
|
||||
.map(airspace => {
|
||||
|
||||
let fillOpacity = 0;
|
||||
let strokeWeight = 1;
|
||||
if (["PROHIBIT", "RESTRICT"].includes(airspace.type))
|
||||
fillOpacity = 0.1;
|
||||
if (highlightedAirspaces.value.includes(airspace.name))
|
||||
fillOpacity = 0.2;
|
||||
if (highlightedAirspaces.value.includes(airspace.name)) {
|
||||
strokeWeight = 2;
|
||||
fillOpacity = 0.3;
|
||||
}
|
||||
|
||||
const data = {
|
||||
name: airspace.name,
|
||||
strokeColor: colorsMap[airspace.type],
|
||||
fillColor: colorsMap[airspace.type],
|
||||
strokeOpacity: 0.5,
|
||||
strokeWeight: 1,
|
||||
strokeWeight,
|
||||
fillOpacity,
|
||||
};
|
||||
|
||||
@@ -146,6 +149,14 @@ const emitMapClick = (data) => {
|
||||
}
|
||||
|
||||
const highlightedAirspaces = ref([]);
|
||||
const highlightAirspace = (airspaceName) => {
|
||||
const airspace = props.airspacesData.find(a => a.name === airspaceName);
|
||||
|
||||
if (airspace) {
|
||||
highlightedAirspaces.value = [airspaceName];
|
||||
displayAirspaceLayers.value[airspace.type] = true;
|
||||
}
|
||||
}
|
||||
|
||||
const handleMapClick = (e) => {
|
||||
const position = {lat: e.latLng.lat(), lng: e.latLng.lng()};
|
||||
@@ -192,7 +203,8 @@ const handleAirportClick = (airport) => {
|
||||
:highlighted-airspaces="highlightedAirspaces"
|
||||
@close="infoWindow.active=false"
|
||||
@add-to-route="emits('add-to-route', $event)"
|
||||
@highlight-airspace="highlightedAirspaces = [$event]"
|
||||
@remove-from-route="emits('remove-from-route', $event)"
|
||||
@highlight-airspace="highlightAirspace"
|
||||
/>
|
||||
|
||||
<template v-for="airspace in airspaces" :key="airspace.name">
|
||||
|
||||
@@ -7,11 +7,23 @@ export const FRAGMENT_AIRPORT_INFO = gql`
|
||||
icaoCode
|
||||
gpsLatitude
|
||||
gpsLongitude
|
||||
elevation
|
||||
reportingPoints {
|
||||
id
|
||||
gpsLatitude
|
||||
gpsLongitude
|
||||
name
|
||||
}
|
||||
frequencies {
|
||||
frequency
|
||||
name
|
||||
}
|
||||
runways {
|
||||
designator
|
||||
heading
|
||||
surface
|
||||
length
|
||||
width
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user