draft planovace

This commit is contained in:
Michal Kváček
2024-03-25 21:59:55 +01:00
parent 02b839674e
commit 9af80cda06
12 changed files with 262 additions and 57 deletions
@@ -0,0 +1,202 @@
<script setup>
import {computed, defineEmits, onMounted, ref, watch} from "vue";
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
import {storeToRefs} from "pinia";
import {useQuasar} from "quasar";
import {commonProps} from "src/composables/inputs";
import {Marker, Polyline} from "vue3-google-map";
import {useAirspacesStore} from "stores/Airspaces";
import MapWrapper from "components/map/MapWrapper.vue";
import {useGeocode} from "src/composables/geocoding";
import {errorObject} from "src/composables/dialog";
import {useAirportsStore} from "stores/Airports";
import {useFlightPlansStore} from "stores/FlightPlans";
const place = ref("");
const {pointsOfInterest} = storeToRefs(usePointsOfInterestStore());
const {airspaces: airspacesData, areAirspacesLoading: isQueryRunning} = storeToRefs(useAirspacesStore())
const $q = useQuasar();
onMounted(() => {
useAirspacesStore().fetch();
usePointsOfInterestStore().fetch({limit: 10000});
useAirportsStore().fetch()
});
const markers = ref([]);
watch(() => markers.value, (newVal) => {
}, {deep: true});
const addPoint = async (point) => {
if (!point) return;
markers.value.push(point);
// {
// label: point.name,
// type: point.type,
//
// position: {
// lat: point.gpsLatitude,
// lng: point.gpsLongitude
// }
// })
}
const track = computed(() => {
return markers.value.map(m => ({lat: m.gpsLatitude, lng: m.gpsLongitude}));
})
const removeMarker = (idx) => {
markers.value.splice(idx, 1);
}
const emits = defineEmits(["update:gpsLatitude", "update:gpsLongitude", "notFound"]);
const {center, zoom, searchGeocode} = useGeocode(emits);
zoom.value = 8;
const {airports} = storeToRefs(useAirportsStore());
const placesOptions = ref(null);
const allPlacesOptions = computed(() => {
return [
...pointsOfInterest.value.map(poi => ({...poi, type: "poi"})),
...airports.value.map(airport => ({
...airport,
name: `${airport.icaoCode} - ${airport.name}`,
type: "airport",
}))
].map(i => ({...i, disabled: !i.gpsLatitude || !i.gpsLongitude}));
});
const placesFilter = (val, update, abort) => {
update(() => {
console.log(val);
if (val && val !== '') {
placesOptions.value = allPlacesOptions.value.filter(p => p.name.includes(val));
console.log(placesOptions.value);
if (placesOptions.value.length === 0) {
searchGeocode(val).then(results => {
placesOptions.value = results.map(result => ({
name: result.formatted_address,
type: "geocode",
id: null,
gpsLatitude: result.geometry.location.lat,
gpsLongitude: result.geometry.location.lng,
}))
});
}
} else {
placesOptions.value = [];
}
})
}
watch(() => place.value, (newVal) => {
addPoint(newVal);
place.value = null;
});
const saveMarkers = () => {
useFlightPlansStore().create({
name: "",
isPublic: false,
markers: markers.value.map(m => ({
name: m.name,
type: m.type,
gpsLatitude: m.gpsLatitude,
gpsLongitude: m.gpsLongitude,
}))
});
}
</script>
<template>
<div class="row">
<div class="col" style="min-width: 1px">
<MapWrapper style="width: 100%; height: 500px" :center="center" :zoom="zoom" :airspaces-data="airspacesData">
<template v-for="marker in markers" :key="marker">
<Marker :options="{label: marker.name, position: {lat: marker.gpsLatitude, lng: marker.gpsLongitude}}"/>
</template>
<Polyline :options="{path: track, geodesic: true, strokeColor: '#ff0000', strokeOpacity: 0.5, strokeWeight: 5}"/>
</MapWrapper>
</div>
<div class="col-12 col-md-5 col-lg-3" v-if="markers.length">
<q-list bordered class="q-ml-md-md">
<template v-for="(marker, i) in markers" :key="marker">
<q-item>
<q-item-section>
<q-item-label>
{{ i + 1 }}. {{ marker.label }}
</q-item-label>
<q-item-section caption>
{{ marker.type }}
</q-item-section>
<q-item-label caption>
<q-btn icon="add" color="green" flat dense round></q-btn>
</q-item-label>
</q-item-section>
<q-item-section middle side>
<div class="text-grey-8 q-gutter-xs">
<!-- <q-btn class="gt-xs" size="12px" flat dense round icon="delete" />-->
<!-- <q-btn class="gt-xs" size="12px" flat dense round icon="done" />-->
<!-- <q-btn size="12px" flat dense round icon="more_vert" />-->
<q-btn color="red" flat round dense icon="delete" @click="removeMarker(i)"/>
</div>
</q-item-section>
</q-item>
</template>
</q-list>
</div>
</div>
<q-select
v-model="place"
label="Místo"
use-input
input-debounce="100"
map-options
emit-value
option-label="name"
option-disable="disabled"
:options="placesOptions"
@filter="placesFilter"
>
<!-- <template #option="{opt}">-->
<!-- <q-item>-->
<!-- <q-item-section>-->
<!-- Option! {{ opt }}-->
<!-- </q-item-section>-->
<!-- </q-item>-->
<!-- </template>-->
</q-select>
<q-btn @click="saveMarkers" color="primary">Save</q-btn>
<!-- <q-input type="text" v-bind="commonProps" v-model="place" label="Misto"/>-->
<q-list bordered v-if="false">
<q-item v-for="poi in pointsOfInterest" :key="poi">
<q-item-section>{{ poi.name }}</q-item-section>
<q-item-section v-if="poi.gpsLatitude">
<q-btn @click="addPoint(poi)">Přidat do trasy</q-btn>
</q-item-section>
</q-item>
<q-item v-if="pointsOfInterest.length === 0 && place !== ''">
<q-btn @click="addPoint(null, place)">Najít {{ place }} na mapě</q-btn>
</q-item>
</q-list>
<!-- <q-btn @click="searchPosition">Najit</q-btn>-->
<!-- <MapWithMarkers :markers="markers" />-->
</template>