feat: implemented map (does not yet support geoJSON)

This commit is contained in:
2025-01-07 00:19:29 +01:00
parent 8ba723e52e
commit 74d00b041f
9 changed files with 403 additions and 50 deletions

View File

@ -33,13 +33,20 @@ export default defineComponent({
<div class="card bg-base-100 w-full shadow-xl" style="">
<div class="card-body">
<h2 class="card-title">{{ localizedUploadHeader }}</h2>
<h2 class="card-title">File Upload</h2>
<button class="btn btn-error close round" @click="close()">
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed">
<path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"/>
</svg>
</button>
<label class="form-control w-full max-w-xs">
<div class="label">
<span class="label-text">Upload a GPX File</span>
</div>
<input type="file" class="file-input file-input-bordered w-full max-w-xs" />
</label>
<button class="btn btn-success">Upload</button>
</div>
</div>
</template>

View File

@ -1,37 +1,64 @@
<script lang="ts">
import {defineComponent, SetupContext} from 'vue';
import { defineComponent, onMounted, ref } from 'vue';
import "leaflet/dist/leaflet.css";
import L from "leaflet";
export default defineComponent({
name: 'map',
setup(_, { emit }: SetupContext) {
return {
name: 'Map',
props: {
geoJsonData: {
type: Object,
required: false,
default: null,
},
},
setup(props) {
const mapDiv = ref<HTMLElement | null>(null); // ref to map container element
onMounted(() => {
if (mapDiv.value) {
const map = L.map(mapDiv.value, {
center: [51.4819, 7.2162], // Beispielkoordinaten, setze deine eigenen
zoom: 13,
});
// Hinzufügen der GeoJSON-Daten zur Karte
if (props.geoJsonData) {
L.geoJSON(props.geoJsonData).addTo(map);
}
// Hinzufügen von OpenStreetMap-Kacheln
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {}).addTo(map);
}
});
return {
mapDiv, // Gebe mapDiv zurück, damit es im Template verwendet wird
};
},
});
</script>
<template>
the map has not yet been implemented
<ul class="menu bg-base-200 lg:menu-horizontal" style="width: 100%;">
<li>
<a>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cloud-upload-fill" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 0a5.53 5.53 0 0 0-3.594 1.342c-.766.66-1.321 1.52-1.464 2.383C1.266 4.095 0 5.555 0 7.318 0 9.366 1.708 11 3.781 11H7.5V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V11h4.188C14.502 11 16 9.57 16 7.773c0-1.636-1.242-2.969-2.834-3.194C12.923 1.999 10.69 0 8 0m-.5 14.5V11h1v3.5a.5.5 0 0 1-1 0"/>
</svg>
Upload
</a>
</li>
<li>
<a @click="toggleSettings">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-sliders" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M11.5 2a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3M9.05 3a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0V3zM4.5 7a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3M2.05 8a2.5 2.5 0 0 1 4.9 0H16v1H6.95a2.5 2.5 0 0 1-4.9 0H0V8zm9.45 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3m-2.45 1a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0v-1z"/>
</svg>
Settings
</a>
</li>
</ul>
<!-- Das ref-Attribut gibt den Container für die Karte an -->
<div ref="mapDiv" style="width: 100vw; height: 80vh; overflow: hidden;"></div>
</template>
<style scoped>
</style>
/* Verhindert, dass die Karte über den Bildschirm hinausgeht */
#mapDiv {
width: 100vw; /* Volle Breite des Viewports */
height: 80vh; /* Volle Höhe des Viewports */
margin: 0; /* Keine Margen */
padding: 0; /* Keine Auffüllung */
overflow: hidden; /* Verhindert ungewolltes Überlaufen */
}
/* Optional: Globale Styles für den Body und html, um das Layout zu normalisieren */
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
</style>

4
web/src/leatflet.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
declare module 'leaflet' {
import * as L from 'leaflet';
export = L;
}

View File

@ -51,7 +51,6 @@ export default defineComponent({
// handles sending webrequests to the backend
const createDriver = async () => {
// TODO: send of post request with new driver and attach it to the grid
const headers: Headers = new Headers()
headers.set('Content-Type', 'application/json')

View File

@ -1,10 +1,60 @@
<script lang="ts">
import {defineComponent, SetupContext} from 'vue';
import {defineComponent, ref, Ref, SetupContext} from 'vue';
import PointCloud from '../components/pointcloud.vue';
import VueDatePicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css'
import Map from '../components/map.vue';
import FileUpload from '../components/fileUpload.vue';
type track = {
id:number
name:string
}
export default defineComponent({
name: 'map',
components: {PointCloud, VueDatePicker, Map, FileUpload},
setup(_, { emit }: SetupContext) {
const showMap:Ref<boolean> = ref(false);
const showCloud:Ref<boolean> = ref(false);
const search:Ref<boolean> = ref(true);
const showUpload:Ref<boolean> = ref(false);
const tracks:Ref<track[]> = ref([{id:0, name:"test"}])
const startSearchDate = ref();
const endSearchDate = ref();
const mapData = ref(null);
const loadTrack = async (id:number) => {
showMap.value = true;
showCloud.value = false;
search.value = false;
}
const toggleUpdload = () => {
}
const getTracks = async() => {
}
const searchTracks = async() => {
}
return {
showMap,
showCloud,
search,
tracks,
loadTrack,
getTracks,
searchTracks,
startSearchDate,
endSearchDate,
mapData,
showUpload
};
},
});
@ -12,7 +62,34 @@ export default defineComponent({
<template>
route
<FileUpload v-if="showUpload" @close="showUpload=false;" style="position:absolute; top: 30VH; width: 80%;"></FileUpload>
<div class="grid grid-flow-col auto-cols-max gap-4">
<div>
<ul class="menu menu-xs bg-base-200 rounded-lg w-full max-w-xs overscroll-auto">
<li> <a v-on:click="showUpload=true; showMap=false;showCloud=false;search=false;"> upload file </a> </li>
<li> <a v-on:click="search=true;showMap=false;showCloud=false;"> filter track </a> </li>
<li><div class="divider"></div></li>
<li v-for="track in tracks"> <a v-on:click="loadTrack(track.id)"> {{ track.name }} </a> </li>
</ul>
</div>
<div style="width: 62%; margin-left: 30%;">
<PointCloud v-if="showCloud && !search"></PointCloud>
</div>
<div v-if="!showMap && !showCloud && search" style="margin-left: 20%; display:flex;">
<div>
start time
<VueDatePicker v-model="startSearchDate"> Search From </VueDatePicker>
</div>
<div style="margin-left: 5%;">
end time
<VueDatePicker v-model="endSearchDate"> Search To </VueDatePicker>
</div>
<button class="btn btn-success" v-on:click="" style="margin-left: 5%; height:60px; width:120px;">Search</button>
</div>
<div v-if="showMap && !search && !showCloud">
<Map style="width: 68VW; margin-left: 10%; border-radius: 10px; border: 1px solid #95a5a6;"></Map>
</div>
</div>
</template>
<style scoped>

View File

@ -3,7 +3,6 @@ import { defineComponent, SetupContext, ref, Ref } from 'vue';
import GetLocalizedText from "../classes/language";
export default defineComponent({
emits: ['close'],
name: 'settings',
setup(_, { emit }: SetupContext) {
var attributeTheme: Ref<string> = ref(document.documentElement.getAttribute("data-theme") ?? "dark")
@ -18,7 +17,7 @@ export default defineComponent({
}
// TODO: if time rework this to function with the new intended settings class
// NOTE: this has low priority as the system inplace allthough not very intuitive works
// NOTE: this has low priority as the system inplace although not very intuitive works
const changeTheme = (theme: string) => {
document.documentElement.setAttribute('data-theme', theme);

View File

@ -1,19 +0,0 @@
<script lang="ts">
import {defineComponent, SetupContext} from 'vue';
export default defineComponent({
name: 'map',
setup(_, { emit }: SetupContext) {
return {
};
},
});
</script>
<template>
upload center
</template>
<style scoped>
</style>