Vicemene funkcni mapova cast planovace
This commit is contained in:
@@ -37,8 +37,14 @@ const {getMarkersFrom} = useFlightPlanUtils();
|
|||||||
|
|
||||||
const infoWindow = ref(infoWindowObject({}));
|
const infoWindow = ref(infoWindowObject({}));
|
||||||
|
|
||||||
const handleMapClick = ({clickCoordinates, airspaces, airport}) => {
|
const handleMapClick = ({clickCoordinates, airspaces, airport, reportingPoint}) => {
|
||||||
infoWindow.value = infoWindowObject({active: true, airspaces, position: clickCoordinates, airport})
|
infoWindow.value = infoWindowObject({
|
||||||
|
active: true,
|
||||||
|
position: clickCoordinates,
|
||||||
|
airspaces,
|
||||||
|
airport,
|
||||||
|
reportingPoint,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMarkerClick = (marker) => {
|
const handleMarkerClick = (marker) => {
|
||||||
@@ -81,7 +87,6 @@ const handleMarkerMove = async (idx, event) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
vkladam na pozici {{ insertPosition }}
|
|
||||||
<MapWrapper
|
<MapWrapper
|
||||||
style="width: 100%; height: 100%; min-height: 500px"
|
style="width: 100%; height: 100%; min-height: 500px"
|
||||||
:center="center"
|
:center="center"
|
||||||
@@ -89,6 +94,7 @@ const handleMarkerMove = async (idx, event) => {
|
|||||||
:airspaces-data="airspaceData"
|
:airspaces-data="airspaceData"
|
||||||
:airports="airports"
|
:airports="airports"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
:fullscreen-control="false"
|
||||||
@map-click="handleMapClick"
|
@map-click="handleMapClick"
|
||||||
>
|
>
|
||||||
<AirspaceInfoWindow
|
<AirspaceInfoWindow
|
||||||
|
|||||||
@@ -55,38 +55,41 @@ const totalTime = computed(() => {
|
|||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
||||||
<template v-for="(segment, i) in props.flightPlan.track" :key="segment">
|
<q-scroll-area style="height: 50vh">
|
||||||
<q-item dense>
|
<template v-for="(segment, i) in props.flightPlan.track" :key="segment">
|
||||||
<q-item-section>
|
<q-item dense>
|
||||||
<q-item-label>{{ segment.from.name }}</q-item-label>
|
<q-item-section>
|
||||||
<q-item-label caption class="q-py-sm" v-if="segment.distance">
|
<q-item-label>{{ segment.from.name }}</q-item-label>
|
||||||
{{ segment.bearing }}°,
|
<q-item-label caption class="q-py-sm" v-if="segment.distance">
|
||||||
{{ segment.distance }} km,
|
{{ segment.bearing }}°,
|
||||||
{{ minutesToHumanReadable(getDuration(segment.distance, props.plannedSpeed)) }}
|
{{ segment.distance }} km,
|
||||||
</q-item-label>
|
{{ minutesToHumanReadable(getDuration(segment.distance, props.plannedSpeed)) }}
|
||||||
<q-item-label>
|
</q-item-label>
|
||||||
<q-btn
|
<q-item-label>
|
||||||
@click="emits('change-insert-position', i+1)"
|
<q-btn
|
||||||
icon="add"
|
@click="emits('change-insert-position', i+1)"
|
||||||
size="sm"
|
icon="add"
|
||||||
class="q-ml-lg q-mb-sm"
|
size="sm"
|
||||||
:round="insertPosition !== i+1"
|
class="q-ml-lg q-mb-sm"
|
||||||
:color="insertPosition === i+1 ? 'primary' : 'grey'"
|
:round="insertPosition !== i+1"
|
||||||
>
|
:color="insertPosition === i+1 ? 'primary' : 'grey'"
|
||||||
<template v-if="insertPosition === i+1">Přidávám sem</template>
|
>
|
||||||
</q-btn>
|
<template v-if="insertPosition === i+1">Přidávám sem</template>
|
||||||
</q-item-label>
|
</q-btn>
|
||||||
</q-item-section>
|
</q-item-label>
|
||||||
</q-item>
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
<q-item dense v-if="segment.to && i === props.flightPlan.track.length - 1">
|
|
||||||
<q-item-section>
|
<q-item dense v-if="segment.to && i === props.flightPlan.track.length - 1">
|
||||||
<q-item-label>
|
<q-item-section>
|
||||||
{{ segment.to.name }}
|
<q-item-label>
|
||||||
</q-item-label>
|
{{ segment.to.name }}
|
||||||
</q-item-section>
|
</q-item-label>
|
||||||
</q-item>
|
</q-item-section>
|
||||||
</template>
|
</q-item>
|
||||||
|
</template>
|
||||||
|
</q-scroll-area>
|
||||||
<q-item>
|
<q-item>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -42,8 +42,15 @@ const {getIcon} = useFlightPlanUtils();
|
|||||||
const {editableNameTypes} = useFlightPlanObjects();
|
const {editableNameTypes} = useFlightPlanObjects();
|
||||||
|
|
||||||
const allPlacesOptions = computed(() => {
|
const allPlacesOptions = computed(() => {
|
||||||
|
|
||||||
|
const reportingPoints = props.airports.map(a => a.reportingPoints.map(r => ({...r, airport: a}))).flat()
|
||||||
return [
|
return [
|
||||||
...props.pointsOfInterest.map(poi => ({...poi, type: "poi"})),
|
...props.pointsOfInterest.map(poi => ({...poi, type: "poi"})),
|
||||||
|
...reportingPoints.map(r => ({
|
||||||
|
...r,
|
||||||
|
name: `${r.airport.icaoCode}:${r.name}`,
|
||||||
|
type: "reportingPoint"
|
||||||
|
})),
|
||||||
...props.airports.map(airport => ({
|
...props.airports.map(airport => ({
|
||||||
...airport,
|
...airport,
|
||||||
name: `${airport.icaoCode} - ${airport.name}`,
|
name: `${airport.icaoCode} - ${airport.name}`,
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ const displayAirspaceLayers = ref({
|
|||||||
TMA: true,
|
TMA: true,
|
||||||
RMZ: false,
|
RMZ: false,
|
||||||
ATZ: true,
|
ATZ: true,
|
||||||
|
PARA: false,
|
||||||
DANGER: false,
|
DANGER: false,
|
||||||
PROHIBIT: true,
|
PROHIBIT: true,
|
||||||
RESTRICT: true,
|
RESTRICT: true,
|
||||||
@@ -68,29 +69,29 @@ const displayAirspaceLayers = ref({
|
|||||||
|
|
||||||
const airspaces = computed(() => {
|
const airspaces = computed(() => {
|
||||||
const colorsMap = {
|
const colorsMap = {
|
||||||
C: "#800080",
|
TMA: "#800080",
|
||||||
D: "#800080",
|
CTR: "#366e36",
|
||||||
CTR: "#00ff00",
|
PROHIBIT: "#FF0000",
|
||||||
P: "#FF0000",
|
|
||||||
RMZ: "#FFdd00",
|
RMZ: "#FFdd00",
|
||||||
R: "#ff6a00",
|
RESTRICT: "#ff6a00",
|
||||||
Q: "#FFA500",
|
DANGER: "#FFA500",
|
||||||
PGZ: "#008000",
|
TRAGA: "#008000",
|
||||||
GSEC: "#008000",
|
|
||||||
ATZ: "#4e7cfc",
|
ATZ: "#4e7cfc",
|
||||||
FIR: '#ffffff'
|
FIR: '#ffffff',
|
||||||
|
PARA: "#000000"
|
||||||
}
|
}
|
||||||
|
|
||||||
return props.airspacesData
|
return props.airspacesData
|
||||||
.filter(airspace => !!colorsMap[airspace.type])
|
.filter(airspace => !!colorsMap[airspace.type])
|
||||||
.filter(airspace => {
|
.filter(airspace => {
|
||||||
if (['C', 'D'].includes(airspace.type)) return displayAirspaceLayers.value.TMA;
|
if (['TMA'].includes(airspace.type)) return displayAirspaceLayers.value.TMA;
|
||||||
if (['PGZ', 'GSEC'].includes(airspace.type)) return displayAirspaceLayers.value.TRAGA;
|
if (['TRAGA'].includes(airspace.type)) return displayAirspaceLayers.value.TRAGA;
|
||||||
if (airspace.type === 'CTR') return displayAirspaceLayers.value.CTR;
|
if (airspace.type === 'CTR') return displayAirspaceLayers.value.CTR;
|
||||||
if (airspace.type === 'RMZ') return displayAirspaceLayers.value.RMZ;
|
if (airspace.type === 'RMZ') return displayAirspaceLayers.value.RMZ;
|
||||||
if (airspace.type === 'Q') return displayAirspaceLayers.value.DANGER;
|
if (airspace.type === 'DANGER') return displayAirspaceLayers.value.DANGER;
|
||||||
if (airspace.type === 'P') return displayAirspaceLayers.value.PROHIBIT;
|
if (airspace.type === 'PROHIBIT') return displayAirspaceLayers.value.PROHIBIT;
|
||||||
if (airspace.type === 'R') return displayAirspaceLayers.value.RESTRICT;
|
if (airspace.type === 'RESTRICT') return displayAirspaceLayers.value.RESTRICT;
|
||||||
|
if (airspace.type === 'PARA') return displayAirspaceLayers.value.PARA;
|
||||||
if (airspace.type === 'ATZ') return displayAirspaceLayers.value.ATZ;
|
if (airspace.type === 'ATZ') return displayAirspaceLayers.value.ATZ;
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
@@ -101,7 +102,7 @@ const airspaces = computed(() => {
|
|||||||
strokeOpacity: 0.3,
|
strokeOpacity: 0.3,
|
||||||
strokeWeight: 3,
|
strokeWeight: 3,
|
||||||
fillColor: colorsMap[airspace.type],
|
fillColor: colorsMap[airspace.type],
|
||||||
fillOpacity: 0,
|
fillOpacity: ["PROHIBIT", "RESTRICT"].includes(airspace.type) ? 0.1 : 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (airspace.mapBounds.length > 0) {
|
if (airspace.mapBounds.length > 0) {
|
||||||
@@ -146,6 +147,11 @@ const handleMapClick = (e) => {
|
|||||||
emits("map-click", {airspaces: getAirspacesAtCoordinates(clickCoordinates), clickCoordinates});
|
emits("map-click", {airspaces: getAirspacesAtCoordinates(clickCoordinates), clickCoordinates});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleReportingPointClick = (airport, reportingPoint) => {
|
||||||
|
const position = {lat: reportingPoint.gpsLatitude, lng: reportingPoint.gpsLongitude};
|
||||||
|
emits("map-click", {clickCoordinates: position, airport, reportingPoint})
|
||||||
|
}
|
||||||
|
|
||||||
const handleAirportClick = (airport) => {
|
const handleAirportClick = (airport) => {
|
||||||
const position = {lat: airport.gpsLatitude, lng: airport.gpsLongitude};
|
const position = {lat: airport.gpsLatitude, lng: airport.gpsLongitude};
|
||||||
emits("map-click", {clickCoordinates: position, airport})
|
emits("map-click", {clickCoordinates: position, airport})
|
||||||
@@ -163,24 +169,35 @@ const handleAirportClick = (airport) => {
|
|||||||
ref="mapRef"
|
ref="mapRef"
|
||||||
>
|
>
|
||||||
<template v-for="airspace in airspaces" :key="airspace.name">
|
<template v-for="airspace in airspaces" :key="airspace.name">
|
||||||
<Polygon :options="airspace" @click=handleMapClick v-if="airspace.path"/>
|
<Polygon :options="airspace" @click="handleMapClick" />
|
||||||
<Circle :options="airspace" @click=handleMapClick v-if="airspace.center && airspace.radius"/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<slot/>
|
||||||
|
|
||||||
<template v-for="airport in airportsOnMap" :key="airport.icaoCode">
|
<template v-for="airport in airportsOnMap" :key="airport.icaoCode">
|
||||||
<CustomMarker
|
<CustomMarker
|
||||||
:options="{position: {lat: airport.gpsLatitude, lng: airport.gpsLongitude}, anchorPoint: 'CENTER'}"
|
:options="{position: {lat: airport.gpsLatitude, lng: airport.gpsLongitude}, anchorPoint: 'CENTER'}"
|
||||||
@click.stop="handleAirportClick(airport)"
|
@click.stop="handleAirportClick(airport)"
|
||||||
>
|
>
|
||||||
<q-chip size="xs">{{ airport.icaoCode }}</q-chip>
|
<q-chip size="xs">{{ airport.icaoCode }}</q-chip>
|
||||||
</CustomMarker>
|
</CustomMarker>
|
||||||
|
|
||||||
|
<template v-if="displayAirspaceLayers.CTR">
|
||||||
|
<CustomMarker
|
||||||
|
v-for="reportingPoint in airport.reportingPoints" :key="reportingPoint.id"
|
||||||
|
:options="{position: {lat: reportingPoint.gpsLatitude, lng: reportingPoint.gpsLongitude, anchorPoint: 'CENTER'}}"
|
||||||
|
@click.stop="handleReportingPointClick(airport, reportingPoint)"
|
||||||
|
:title="`${airport.icaoCode}: ${reportingPoint.name}`"
|
||||||
|
>
|
||||||
|
<q-icon name="mdi-triangle"/>
|
||||||
|
</CustomMarker>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<slot/>
|
|
||||||
|
|
||||||
<CustomControl position="BOTTOM_CENTER" class="text-center" v-if="showLayerControls">
|
<CustomControl position="BOTTOM_CENTER" class="text-center" v-if="showLayerControls">
|
||||||
<q-card class="q-my-md q-mx-auto q-px-lg" style="max-width: 98%;">
|
<q-card class="q-my-md q-mx-auto q-px-lg" style="max-width: 98%;">
|
||||||
<q-checkbox v-model="displayAirspaceLayers.CTR" label="M/CTR"/>
|
<q-checkbox v-model="displayAirspaceLayers.CTR" label="CTR"/>
|
||||||
<q-checkbox v-model="displayAirspaceLayers.TMA" label="TMA"/>
|
<q-checkbox v-model="displayAirspaceLayers.TMA" label="TMA"/>
|
||||||
<q-checkbox v-model="displayAirspaceLayers.RMZ" label="RMZ"/>
|
<q-checkbox v-model="displayAirspaceLayers.RMZ" label="RMZ"/>
|
||||||
<q-checkbox v-model="displayAirspaceLayers.ATZ" label="ATZ"/>
|
<q-checkbox v-model="displayAirspaceLayers.ATZ" label="ATZ"/>
|
||||||
@@ -188,6 +205,7 @@ const handleAirportClick = (airport) => {
|
|||||||
<q-checkbox v-model="displayAirspaceLayers.PROHIBIT" label="Zakázané prostory"/>
|
<q-checkbox v-model="displayAirspaceLayers.PROHIBIT" label="Zakázané prostory"/>
|
||||||
<q-checkbox v-model="displayAirspaceLayers.RESTRICT" label="TRA"/>
|
<q-checkbox v-model="displayAirspaceLayers.RESTRICT" label="TRA"/>
|
||||||
<q-checkbox v-model="displayAirspaceLayers.TRAGA" label="TRAGA"/>
|
<q-checkbox v-model="displayAirspaceLayers.TRAGA" label="TRAGA"/>
|
||||||
|
<q-checkbox v-model="displayAirspaceLayers.PARA" label="PARA"/>
|
||||||
<q-checkbox v-model="displayAirspaceLayers.AIRPORTS" label="Letiště"/>
|
<q-checkbox v-model="displayAirspaceLayers.AIRPORTS" label="Letiště"/>
|
||||||
<q-checkbox v-model="displayAirspaceLayers.FIELDSTRIP" label="SLZ plochy"/>
|
<q-checkbox v-model="displayAirspaceLayers.FIELDSTRIP" label="SLZ plochy"/>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const useFlightPlanObjects = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const infoWindowObject = ({active, position, marker, poi, airport, airspaces}) => {
|
const infoWindowObject = ({active, position, marker, poi, airport, reportingPoint, airspaces}) => {
|
||||||
if (!position) position = {};
|
if (!position) position = {};
|
||||||
if (!position.lat) position.lat = 0;
|
if (!position.lat) position.lat = 0;
|
||||||
if (!position.lng) position.lng = 0;
|
if (!position.lng) position.lng = 0;
|
||||||
@@ -60,9 +60,15 @@ export const useFlightPlanObjects = () => {
|
|||||||
let title = null;
|
let title = null;
|
||||||
|
|
||||||
if (airport) {
|
if (airport) {
|
||||||
title = `${airport.icaoCode} (${airport.name})`;
|
if (!reportingPoint) {
|
||||||
position.lat = airport.gpsLatitude;
|
title = `${airport.icaoCode} (${airport.name})`;
|
||||||
position.lng = airport.gpsLongitude;
|
position.lat = airport.gpsLatitude;
|
||||||
|
position.lng = airport.gpsLongitude;
|
||||||
|
} else {
|
||||||
|
title = `${airport.icaoCode}:${reportingPoint.name}`
|
||||||
|
position.lat = reportingPoint.gpsLatitude;
|
||||||
|
position.lng = reportingPoint.gpsLongitude;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (marker) {
|
if (marker) {
|
||||||
@@ -77,7 +83,7 @@ export const useFlightPlanObjects = () => {
|
|||||||
position.lng = poi.gpsLongitude;
|
position.lng = poi.gpsLongitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {title, active, position, airspaces, poi, marker, airport};
|
return {title, active, position, airspaces, poi, marker, airport, reportingPoint};
|
||||||
};
|
};
|
||||||
|
|
||||||
return {markerObject, googleMapsMarkerObject, googleMapsCustomMarkerObject, infoWindowObject, editableNameTypes}
|
return {markerObject, googleMapsMarkerObject, googleMapsCustomMarkerObject, infoWindowObject, editableNameTypes}
|
||||||
|
|||||||
@@ -7,5 +7,11 @@ export const FRAGMENT_AIRPORT_INFO = gql`
|
|||||||
icaoCode
|
icaoCode
|
||||||
gpsLatitude
|
gpsLatitude
|
||||||
gpsLongitude
|
gpsLongitude
|
||||||
|
reportingPoints {
|
||||||
|
id
|
||||||
|
gpsLatitude
|
||||||
|
gpsLongitude
|
||||||
|
name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
|
import {FRAGMENT_AIRPORT_INFO} from "src/graphql/fragments/airport";
|
||||||
|
|
||||||
export const AIRPORTS_LIST = gql`
|
export const AIRPORTS_LIST = gql`
|
||||||
query AirportsList {
|
query AirportsList {
|
||||||
airports {
|
airports {
|
||||||
id
|
...airportInfo
|
||||||
name
|
|
||||||
icaoCode
|
|
||||||
gpsLatitude
|
|
||||||
gpsLongitude
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${FRAGMENT_AIRPORT_INFO}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -6,11 +6,7 @@ export const AIRSPACE_LIST = gql`
|
|||||||
airspaces {
|
airspaces {
|
||||||
name
|
name
|
||||||
type
|
type
|
||||||
mapCenter {
|
|
||||||
lat
|
|
||||||
lng
|
|
||||||
}
|
|
||||||
radius
|
|
||||||
mapBounds {
|
mapBounds {
|
||||||
lat
|
lat
|
||||||
lng
|
lng
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ const insertAtPosition = ref(flightPlanMarkers.value.length);
|
|||||||
@markers-changed="handleMarkersChanges"
|
@markers-changed="handleMarkersChanges"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-5 col-lg-3">
|
<div class="col-12 col-md-5 col-lg-2">
|
||||||
<FlightPlanMarkersList
|
<FlightPlanMarkersList
|
||||||
:insert-position="insertAtPosition"
|
:insert-position="insertAtPosition"
|
||||||
:flight-plan="flightPlan"
|
:flight-plan="flightPlan"
|
||||||
|
|||||||
Reference in New Issue
Block a user