travel-steps/summer2024-frontend/src/views/MapView.vue
Nicolas Froger 45429d26d9
frontend: map: use explicit import
Signed-off-by: Nicolas Froger <nicolas@kektus.xyz>
2024-07-27 16:49:23 +02:00

145 lines
4.6 KiB
Vue

<script setup>
import { Map, Layers, Sources, MapControls, Geometries, Styles } from 'vue3-openlayers'
import { usePostsStore } from '@/stores/posts.js'
import { computed, onMounted, ref } from 'vue'
import { Camera, Goal, MapPin } from 'lucide-vue-next'
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '@/components/ui/tooltip/index.js'
import { useLocationStore } from '@/stores/location.js'
import { fromLonLat } from 'ol/proj.js'
const postStore = usePostsStore()
const locationStore = useLocationStore()
const postsLinesCoordinates = computed(() => {
const coords = []
if (locationStore.lastLocation != null) {
coords.push(locationStore.lastLocation.projectedCoordinates)
}
for (const post of postStore.posts) {
coords.push(post.projectedCoordinates)
}
return coords
})
onMounted(() => {
postStore.fetchPosts()
locationStore.fetchLocation()
})
const goalLocations = ref([
{ name: 'Amsterdam', coords: fromLonLat([4.893611, 52.372778]) },
{ name: 'Berlin', coords: fromLonLat([13.405, 52.52]) },
{ name: 'Prague', coords: fromLonLat([14.421389, 50.0875]) },
{ name: 'Varsovie', coords: fromLonLat([21.011111, 52.23]) },
{ name: 'Vilnius', coords: fromLonLat([25.28, 54.687222]) },
{ name: 'Riga', coords: fromLonLat([24.106389, 56.948889]) },
{ name: 'Tallinn', coords: fromLonLat([24.745278, 59.437222]) }
])
</script>
<template>
<div class="fixed h-full w-full">
<Map.OlMap
:loadTilesWhileAnimating="true"
:loadTilesWhileInteracting="true"
class="h-full w-full"
>
<Map.OlView ref="view" :zoom="3.6" :center="[652293.6169027708, 6425265.202945196]" />
<Layers.OlTileLayer>
<Sources.OlSourceOsm />
</Layers.OlTileLayer>
<MapControls.OlScalelineControl />
<Map.OlOverlay
v-for="post in postStore.posts"
:key="post.id"
:position="post.projectedCoordinates"
:autoPan="true"
>
<TooltipProvider>
<Tooltip :default-open="true">
<TooltipTrigger as-child>
<RouterLink :to="{ name: 'home', hash: '#post-' + post.id }">
<div
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-indigo-950 hover:bg-indigo-900 transition-colors duration-200"
>
<Camera size="16" />
</div>
</RouterLink>
</TooltipTrigger>
<TooltipContent>
<p>{{ post.formatedDate }}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</Map.OlOverlay>
<Map.OlOverlay
v-if="locationStore.lastLocation != null"
:position="locationStore.lastLocation.projectedCoordinates"
:autoPan="true"
>
<TooltipProvider>
<Tooltip :default-open="true">
<TooltipTrigger as-child>
<div
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-rose-950 hover:bg-rose-900 transition-colors duration-200"
>
<MapPin size="16" />
</div>
</TooltipTrigger>
<TooltipContent>
<p>Dernière position, {{ locationStore.lastLocation.formatedDate }}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</Map.OlOverlay>
<Map.OlOverlay
v-for="loc in goalLocations"
:key="loc.name"
:position="loc.coords"
:autoPan="true"
>
<TooltipProvider>
<Tooltip>
<TooltipTrigger as-child>
<div
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-emerald-800 hover:bg-emerald-700 transition-colors duration-200"
>
<Goal size="16" />
</div>
</TooltipTrigger>
<TooltipContent>
<p>Objectif : {{ loc.name }}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</Map.OlOverlay>
<Layers.OlVectorLayer v-if="postsLinesCoordinates.length > 1">
<Sources.OlSourceVector>
<Map.OlFeature ref="profileFeatureRef">
<Geometries.OlGeomLineString
:coordinates="postsLinesCoordinates"
></Geometries.OlGeomLineString>
<Styles.OlStyle>
<Styles.OlStyleStroke
color="white"
width="5"
:lineDash="[15, 15]"
></Styles.OlStyleStroke>
</Styles.OlStyle>
</Map.OlFeature>
</Sources.OlSourceVector>
</Layers.OlVectorLayer>
</Map.OlMap>
</div>
</template>
<style scoped></style>