155 lines
4.3 KiB
Vue
155 lines
4.3 KiB
Vue
<script setup>
|
|
import {computed, ref, watch} from "vue";
|
|
import {Marker, CustomMarker, Polyline} from "vue3-google-map";
|
|
import MapWrapper from "components/map/MapWrapper.vue";
|
|
import {useFlightPlanCalculations, useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
|
|
import {useGeocode} from "src/composables/geocoding";
|
|
|
|
const props = defineProps({
|
|
flightPlan: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
airspaceData: {
|
|
type: Array,
|
|
required: true
|
|
},
|
|
airports: {
|
|
type: Array,
|
|
required: true,
|
|
},
|
|
pointsOfInterest: {
|
|
type: Array,
|
|
required: true
|
|
},
|
|
insertPosition: {
|
|
type: Number,
|
|
required: false,
|
|
default: null
|
|
},
|
|
});
|
|
const emits = defineEmits(["markers-changed", "change-insert-position"]);
|
|
|
|
const {center} = useGeocode();
|
|
|
|
const {markerObject, googleMapsMarkerObject, editableNameTypes} = useFlightPlanObjects();
|
|
const {getMarkersFrom} = useFlightPlanUtils();
|
|
const {getDuration} = useFlightPlanCalculations();
|
|
|
|
const mapWrap = ref(null);
|
|
|
|
const handleMarkerClick = (marker) => {
|
|
mapWrap.value.openInfoWindow({marker});
|
|
}
|
|
|
|
const markers = ref([]);
|
|
watch(() => props.flightPlan.track, (newVal) => {
|
|
markers.value = getMarkersFrom(props.flightPlan);
|
|
}, {immediate: true, deep: true});
|
|
|
|
const track = computed(() => markers.value.map(m => ({lat: m.gpsLatitude, lng: m.gpsLongitude})));
|
|
const trackAids = computed(() => props.flightPlan.track.map(p => ({
|
|
...p,
|
|
anchorPoint: 'CENTER',
|
|
bearing: p.bearing,
|
|
distance: p.distance,
|
|
position: {
|
|
lat: (p.from.gpsLatitude + p.to.gpsLatitude) / 2,
|
|
lng: (p.from.gpsLongitude + p.to.gpsLongitude) / 2
|
|
}
|
|
}
|
|
)));
|
|
const displayTrackAids = ref(true);
|
|
|
|
const addMarker = async (point) => {
|
|
if (!point) return;
|
|
|
|
const insertAt = Math.min(markers.value.length, props.insertPosition);
|
|
markers.value.splice(insertAt, 0, markerObject({...point}));
|
|
|
|
emits("markers-changed", markers.value);
|
|
emits("change-insert-position", insertAt + 1);
|
|
}
|
|
|
|
const removeMarker = (infoWindow) => {
|
|
const idx = markers.value.findIndex(i => i.gpsLatitude === infoWindow.position.lat && i.gpsLongitude === infoWindow.position.lng);
|
|
|
|
if (!idx) return;
|
|
|
|
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());
|
|
markers.value[idx].gpsLatitude = event.lat();
|
|
markers.value[idx].gpsLongitude = event.lng();
|
|
markers.value[idx].type = "mapPoint"
|
|
|
|
emits("markers-changed", markers.value);
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<MapWrapper
|
|
ref="mapWrap"
|
|
style="width: 100%; height: 65vh; min-height: 500px"
|
|
:center="center"
|
|
:zoom="8"
|
|
:track="{path: track, geodesic: true, strokeColor: '#ff00ff', strokeOpacity: 1, strokeWeight: 3}"
|
|
:points-of-interest="pointsOfInterest"
|
|
:airspaces-data="airspaceData"
|
|
:airports="airports"
|
|
v-bind="$attrs"
|
|
:fullscreen-control="false"
|
|
:show-info-window="true"
|
|
:show-layer-controls="true"
|
|
:allow-add-marker="insertPosition !== null"
|
|
@add-to-route="addMarker"
|
|
@remove-from-route="removeMarker"
|
|
>
|
|
<template v-for="(marker, i) in markers" :key="marker.name">
|
|
<!-- TODO: ve verejne casti by nemel byt draggable!-->
|
|
<Marker
|
|
v-if="editableNameTypes.includes(marker.type)"
|
|
:options="googleMapsMarkerObject(marker)"
|
|
@click="handleMarkerClick(marker)"
|
|
@dragend="handleMarkerMove(i, $event.latLng)"
|
|
/>
|
|
</template>
|
|
|
|
<template v-if="displayTrackAids">
|
|
<template v-for="marker in trackAids" :key="marker">
|
|
<CustomMarker :options="marker" class="track-info-marker">
|
|
<div class="track-info" :style='`transform: rotate(${marker.bearing}deg)`'>
|
|
{{ marker.bearing }}° <br>
|
|
{{ getDuration(marker.distance, flightPlan.plannedSpeed) }}'
|
|
</div>
|
|
</CustomMarker>
|
|
</template>
|
|
</template>
|
|
|
|
<template #layersControlsEnd>
|
|
<q-checkbox v-model="displayTrackAids" label="Zobrazovat navigaci po trase?"/>
|
|
</template>
|
|
</MapWrapper>
|
|
</template>
|
|
|
|
<style>
|
|
.track-info {
|
|
background: rgba(128, 128, 128, 0.5);
|
|
color: white;
|
|
border: solid 2px rgba(0, 0, 0, 0.87);
|
|
padding: 5px;
|
|
margin: 5px;
|
|
font-size: 12pt;
|
|
font-weight: bold;
|
|
transform-origin: 50% 50%;
|
|
}
|
|
|
|
.track-info-marker {
|
|
z-index: 999;
|
|
}
|
|
</style>
|