fix: 🐛 fixed weirdness in code and fixed bug that prevented point cloud of rendering properly
This commit is contained in:
parent
9b46ac186d
commit
20ac0faa75
@ -36,6 +36,7 @@ export default defineComponent({
|
|||||||
const mapDiv = ref<HTMLElement | null>(null); // ref to map container element
|
const mapDiv = ref<HTMLElement | null>(null); // ref to map container element
|
||||||
const mapInstance = ref<any>(null); // reference for the Leaflet map
|
const mapInstance = ref<any>(null); // reference for the Leaflet map
|
||||||
const track: Ref<Track> = ref({ id: 0, name: "N/A", driver: "N/A", vehicle: { name: "N/A", licenseplate: "N/A" }, distance: 0.0 })
|
const track: Ref<Track> = ref({ id: 0, name: "N/A", driver: "N/A", vehicle: { name: "N/A", licenseplate: "N/A" }, distance: 0.0 })
|
||||||
|
const multiple:Ref<boolean> = ref(props.multiple);
|
||||||
|
|
||||||
const initializeMap = () => {
|
const initializeMap = () => {
|
||||||
if (mapDiv.value) {
|
if (mapDiv.value) {
|
||||||
@ -56,7 +57,6 @@ export default defineComponent({
|
|||||||
const clearMap = () => {
|
const clearMap = () => {
|
||||||
if (mapInstance.value) {
|
if (mapInstance.value) {
|
||||||
mapInstance.value.eachLayer((layer: any) => {
|
mapInstance.value.eachLayer((layer: any) => {
|
||||||
// Nur Layer entfernen, die keine Basemap sind
|
|
||||||
if (!(layer instanceof L.TileLayer)) {
|
if (!(layer instanceof L.TileLayer)) {
|
||||||
mapInstance.value.removeLayer(layer);
|
mapInstance.value.removeLayer(layer);
|
||||||
}
|
}
|
||||||
@ -94,32 +94,35 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Beobachte geoJsonData und füge sie der Karte hinzu, wenn sie sich ändert
|
|
||||||
watch(() => props.geoJsonData, (newData) => {
|
watch(() => props.geoJsonData, (newData) => {
|
||||||
if (newData) {
|
if (newData) {
|
||||||
console.log("Neue GeoJSON-Daten erhalten:", newData);
|
console.log("loading GeoJSON:", newData);
|
||||||
|
|
||||||
if (mapInstance.value) {
|
if (mapInstance.value) {
|
||||||
// Karte bereinigen
|
if (!props.multiple){
|
||||||
clearMap();
|
clearMap();
|
||||||
|
}
|
||||||
|
|
||||||
// Neue GeoJSON-Daten hinzufügen
|
|
||||||
var geoJsonLayer = L.geoJSON(newData).addTo(mapInstance.value);
|
var geoJsonLayer = L.geoJSON(newData).addTo(mapInstance.value);
|
||||||
|
|
||||||
// Metadaten des Tracks abrufen (z. B. für den ersten Track, falls ID bekannt)
|
// pull meta data for for a single track
|
||||||
getTrackMeta(props.track);
|
// function wont be called if multiple tracks are loaded
|
||||||
|
if (!props.multiple) {
|
||||||
|
getTrackMeta(props.track);
|
||||||
|
}
|
||||||
|
|
||||||
// Karte an die neuen GeoJSON-Daten anpassen
|
// move camera view according to loaded track
|
||||||
const bounds = geoJsonLayer.getBounds();
|
const bounds = geoJsonLayer.getBounds();
|
||||||
mapInstance.value.fitBounds(bounds);
|
mapInstance.value.fitBounds(bounds);
|
||||||
} else {
|
} else {
|
||||||
console.error("Die Karte oder GeoJSON-Daten sind nicht verfügbar.");
|
console.error("Map or GeoJSON data not available.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mapDiv,
|
mapDiv,
|
||||||
|
multiple,
|
||||||
track
|
track
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -129,7 +132,7 @@ export default defineComponent({
|
|||||||
<template>
|
<template>
|
||||||
<div ref="mapDiv" style="width: 70vw; height: 75vh; overflow: hidden;"></div>
|
<div ref="mapDiv" style="width: 70vw; height: 75vh; overflow: hidden;"></div>
|
||||||
<br>
|
<br>
|
||||||
<div class="overflow-x-auto" style="width: 70vw;">
|
<div class="overflow-x-auto" style="width: 70vw;" v-if="!multiple">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<!-- head -->
|
<!-- head -->
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -1,122 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { defineComponent, onMounted, PropType, ref, watch } from "vue";
|
|
||||||
import "leaflet/dist/leaflet.css";
|
|
||||||
import L from "leaflet";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "MapMultiple",
|
|
||||||
props: {
|
|
||||||
tracks: {
|
|
||||||
type: Array as PropType<number[]>, // Array von IDs
|
|
||||||
default: () => [],
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup(props) {
|
|
||||||
const mapDiv = ref<HTMLElement | null>(null); // Ref für die Karten-Div
|
|
||||||
const mapInstance = ref<L.Map | null>(null); // Ref für die Leaflet-Karte
|
|
||||||
const geoJsonLayers = ref<L.LayerGroup | null>(null); // Ref für GeoJSON-Layer
|
|
||||||
|
|
||||||
// Initialisiert die Leaflet-Karte
|
|
||||||
const initializeMap = () => {
|
|
||||||
if (!mapDiv.value) {
|
|
||||||
console.error("mapDiv ist nicht verfügbar.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log("Initialisiere Karte...");
|
|
||||||
mapInstance.value = L.map(mapDiv.value, {
|
|
||||||
center: [51.4819, 7.2162], // Standardzentrum
|
|
||||||
zoom: 13,
|
|
||||||
});
|
|
||||||
|
|
||||||
// OpenStreetMap-Tiles hinzufügen
|
|
||||||
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {}).addTo(
|
|
||||||
mapInstance.value
|
|
||||||
);
|
|
||||||
|
|
||||||
// Initialisiere einen LayerGroup-Container für GeoJSON-Daten
|
|
||||||
geoJsonLayers.value = L.layerGroup().addTo(mapInstance.value);
|
|
||||||
console.log("Karte erfolgreich initialisiert.");
|
|
||||||
};
|
|
||||||
|
|
||||||
// Lädt GeoJSON-Daten für eine bestimmte Track-ID
|
|
||||||
const loadTrack = async (id: number) => {
|
|
||||||
console.log(`Lade Daten für Track ${id}...`);
|
|
||||||
try {
|
|
||||||
const response = await fetch(`http://localhost:5000/track?id=${id}`);
|
|
||||||
if (!response.ok) {
|
|
||||||
console.error(`Fehler beim Laden von Track ${id}:`, response.statusText);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const geoJson = await response.json();
|
|
||||||
console.log(`GeoJSON für Track ${id} erhalten:`, geoJson);
|
|
||||||
return geoJson;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Fehler beim Laden von Track ${id}:`, error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fügt GeoJSON-Daten zur Karte hinzu
|
|
||||||
const addGeoJsonToMap = (geoJson: any) => {
|
|
||||||
if (!geoJsonLayers.value) {
|
|
||||||
console.error("GeoJSON-Layer ist nicht initialisiert.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const layer = L.geoJSON(geoJson);
|
|
||||||
geoJsonLayers.value.addLayer(layer);
|
|
||||||
|
|
||||||
// Fit the map bounds to the newly added layer
|
|
||||||
if (mapInstance.value) {
|
|
||||||
mapInstance.value.fitBounds(layer.getBounds());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.tracks,
|
|
||||||
async (newTracks) => {
|
|
||||||
console.log("Tracks geändert:", newTracks);
|
|
||||||
|
|
||||||
if (!mapInstance.value) {
|
|
||||||
console.error("Karte ist noch nicht initialisiert.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entferne alle vorhandenen GeoJSON-Layer
|
|
||||||
if (geoJsonLayers.value) {
|
|
||||||
geoJsonLayers.value.clearLayers();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const trackId of newTracks) {
|
|
||||||
const geoJson = await loadTrack(trackId);
|
|
||||||
if (geoJson) {
|
|
||||||
await addGeoJsonToMap(geoJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
console.log("Komponente gemountet.");
|
|
||||||
initializeMap();
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
mapDiv,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div ref="mapDiv" id="mapDiv"></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
#mapDiv {
|
|
||||||
width: 100%;
|
|
||||||
height: 75vh;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -35,14 +35,63 @@ export default defineComponent({
|
|||||||
const tooltipRef: Ref<HTMLDivElement | null> = ref(null);
|
const tooltipRef: Ref<HTMLDivElement | null> = ref(null);
|
||||||
const tooltipText = ref("");
|
const tooltipText = ref("");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const legend = ref<Record<number, string>>({});
|
const legend = ref<Record<string, string>>({});
|
||||||
const driverColors = ref<Record<number, string>>({});
|
const driverColors = ref<Record<string, string>>({});
|
||||||
|
var drivers:driver[] = [];
|
||||||
|
const points:Route[] = props.routes;
|
||||||
|
|
||||||
const close = () => {
|
// handles sending webrequests to the backend
|
||||||
emit("close");
|
const getDrivers = async () => {
|
||||||
};
|
|
||||||
|
const headers: Headers = new Headers()
|
||||||
|
|
||||||
|
headers.set('Content-Type', 'application/json')
|
||||||
|
headers.set('Accept', 'application/json')
|
||||||
|
|
||||||
|
const request: RequestInfo = new Request("http://localhost:5000/driver", {
|
||||||
|
method: "GET",
|
||||||
|
headers: headers
|
||||||
|
})
|
||||||
|
|
||||||
|
var response = await fetch(request)
|
||||||
|
|
||||||
|
// make sure the request was successfull
|
||||||
|
if (response.ok) {
|
||||||
|
|
||||||
|
var jsonBody = await response.json()
|
||||||
|
|
||||||
|
// convert vehicles from json response to processable data
|
||||||
|
for (let i = 0; i < jsonBody.length; i++) {
|
||||||
|
let driver = jsonBody[i]
|
||||||
|
|
||||||
|
drivers.push({ id: driver["id"], name: driver["name"] })
|
||||||
|
const color = new THREE.Color(`hsl(${(i * 360) / drivers.length}, 70%, 50%)`);
|
||||||
|
driverColors.value[driver["id"]] = color.getStyle();
|
||||||
|
console.log(color.getStyle())
|
||||||
|
legend.value[driver["id"]] = driver["name"];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(await response.text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assigns a driver to a point based on the points driver id
|
||||||
|
const assignDriverToPoint = (points:Route[]) => {
|
||||||
|
return points.reduce((acc, point) => {
|
||||||
|
|
||||||
|
const driverId = point.driver.id;
|
||||||
|
console.log(`driverid: ${driverId}`)
|
||||||
|
acc[driverId] = acc[driverId] || [];
|
||||||
|
acc[driverId].push(point);
|
||||||
|
return acc;
|
||||||
|
}, {} as Record<number, Route[]>);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// runs only when component has fully mounted
|
||||||
|
onMounted(async () => {
|
||||||
|
await getDrivers();
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (!canvasRef.value) return;
|
if (!canvasRef.value) return;
|
||||||
|
|
||||||
console.log(`routes: ${props.routes}`)
|
console.log(`routes: ${props.routes}`)
|
||||||
@ -58,38 +107,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
const groupedPoints = assignDriverToPoint(points)
|
const groupedPoints = assignDriverToPoint(points)
|
||||||
|
|
||||||
// Beispiel-Daten (Fahrer mit ID und Punkten)
|
|
||||||
const drivers = [
|
|
||||||
{ id: 1, name: "Alice" },
|
|
||||||
{ id: 2, name: "Bob" },
|
|
||||||
{ id: 3, name: "Charlie" },
|
|
||||||
{ id: 4, name: "Dave" },
|
|
||||||
{ id: 5, name: "Eve" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const points: Route[] = Array.from({ length: 100 }, (_, i) => ({
|
|
||||||
name: `Route ${i + 1}`,
|
|
||||||
id: i + 1,
|
|
||||||
time: new Date(Date.now() - i * 1000 * 60),
|
|
||||||
driver: drivers[i % drivers.length], // Fahrer zuweisen
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Nach Fahrern gruppieren
|
|
||||||
const groupedPoints = points.reduce((acc, point) => {
|
|
||||||
const driverId = point.driver.id;
|
|
||||||
acc[driverId] = acc[driverId] || [];
|
|
||||||
acc[driverId].push(point);
|
|
||||||
return acc;
|
|
||||||
}, {} as Record<number, Route[]>);
|
|
||||||
|
|
||||||
// Farben für Fahrer generieren und der Legende zuweisen
|
|
||||||
drivers.forEach((driver, index) => {
|
|
||||||
const color = new THREE.Color(`hsl(${(index * 360) / drivers.length}, 70%, 50%)`);
|
|
||||||
driverColors.value[driver.id] = color.getStyle(); // Farbwert für die Legende
|
|
||||||
legend.value[driver.id] = driver.name; // Fahrernamen für die Legende
|
|
||||||
});
|
|
||||||
|
|
||||||
// Punktwolke erstellen
|
|
||||||
const geometry = new THREE.BufferGeometry();
|
const geometry = new THREE.BufferGeometry();
|
||||||
const vertices: number[] = [];
|
const vertices: number[] = [];
|
||||||
const colors: number[] = [];
|
const colors: number[] = [];
|
||||||
@ -102,20 +119,37 @@ export default defineComponent({
|
|||||||
// Berechnungen für den Mittelpunkt der Punktwolke
|
// Berechnungen für den Mittelpunkt der Punktwolke
|
||||||
let sumX = 0, sumY = 0, sumZ = 0;
|
let sumX = 0, sumY = 0, sumZ = 0;
|
||||||
|
|
||||||
|
const getColorForDriver = (driverId: number) => {
|
||||||
|
const color = driverColors.value[driverId];
|
||||||
|
if (!color) {
|
||||||
|
console.error(`No color found for driver ID ${driverId}`);
|
||||||
|
return "#FFFFFF"; // Rückfallfarbe, wenn keine Farbe gefunden wurde
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
};
|
||||||
|
|
||||||
|
// complicated math things
|
||||||
Object.entries(groupedPoints).forEach(([driverIdStr, driverPoints], index) => {
|
Object.entries(groupedPoints).forEach(([driverIdStr, driverPoints], index) => {
|
||||||
const driverId = parseInt(driverIdStr, 10);
|
const driverId = parseInt(driverIdStr, 10);
|
||||||
const color = new THREE.Color(driverColors.value[driverId]); // Die Farbe aus `driverColors`
|
console.log("Driver Colors:", driverColors.value[driverIdStr]);
|
||||||
|
|
||||||
// Berechnung des Abstands auf der X-Achse basierend auf der Fahrer-ID
|
if (!driverColors.value[driverId]) {
|
||||||
|
console.error(`Missing color for Driver ID: ${driverId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const color = new THREE.Color(driverColors.value[driverId]);
|
||||||
|
console.log(`Color for Driver ${driverId}:`, driverColors.value[driverId]);
|
||||||
|
|
||||||
|
// calculate offset base on driverid
|
||||||
offsetX += offsetXStep;
|
offsetX += offsetXStep;
|
||||||
|
|
||||||
driverPoints.forEach(() => {
|
driverPoints.forEach(() => {
|
||||||
// Zufällige Position innerhalb eines Bereichs
|
// calculate random position in the area of a driver
|
||||||
const x = offsetX + (Math.random() - 0.5) * 2;
|
const x = offsetX + (Math.random() - 0.5) * 2;
|
||||||
const y = (Math.random() - 0.5) * 6;
|
const y = (Math.random() - 0.5) * 6;
|
||||||
const z = (Math.random() - 0.5) * 6;
|
const z = (Math.random() - 0.5) * 6;
|
||||||
|
|
||||||
// Berechnungen für den Mittelpunkt
|
// calculate center
|
||||||
sumX += x;
|
sumX += x;
|
||||||
sumY += y;
|
sumY += y;
|
||||||
sumZ += z;
|
sumZ += z;
|
||||||
@ -124,13 +158,13 @@ export default defineComponent({
|
|||||||
colors.push(color.r, color.g, color.b);
|
colors.push(color.r, color.g, color.b);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mittelpunkt der Punktwolke berechnen
|
// Mittelpunkt der Punktwolke berechnen
|
||||||
const centerX = sumX / totalPoints;
|
const centerX = sumX / totalPoints;
|
||||||
const centerY = sumY / totalPoints;
|
const centerY = sumY / totalPoints;
|
||||||
const centerZ = sumZ / totalPoints;
|
const centerZ = sumZ / totalPoints;
|
||||||
|
|
||||||
// Punktwolke verschieben, damit der Mittelpunkt im Ursprung ist
|
// put cloud centered on the canvase
|
||||||
const offset = new THREE.Vector3(-centerX, -centerY, -centerZ);
|
const offset = new THREE.Vector3(-centerX, -centerY, -centerZ);
|
||||||
for (let i = 0; i < vertices.length; i += 3) {
|
for (let i = 0; i < vertices.length; i += 3) {
|
||||||
vertices[i] += offset.x;
|
vertices[i] += offset.x;
|
||||||
@ -143,7 +177,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
const material = new THREE.PointsMaterial({
|
const material = new THREE.PointsMaterial({
|
||||||
vertexColors: true,
|
vertexColors: true,
|
||||||
vertexColors: true, // Farben pro Punkt verwenden
|
|
||||||
size: 0.3,
|
size: 0.3,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -196,30 +229,10 @@ export default defineComponent({
|
|||||||
tooltipRef.value.style.top = `${tooltipY + 10}px`; // 10px Abstand zum Punkt
|
tooltipRef.value.style.top = `${tooltipY + 10}px`; // 10px Abstand zum Punkt
|
||||||
|
|
||||||
tooltipText.value = `${point.driver.name}: ${point.name} (${point.time.toLocaleString()})`;
|
tooltipText.value = `${point.driver.name}: ${point.name} (${point.time.toLocaleString()})`;
|
||||||
|
|
||||||
// 3D-Koordinaten des Punktes holen
|
|
||||||
const positionArray = pointCloud.geometry.attributes.position.array;
|
|
||||||
const x = positionArray[intersectIndex * 3];
|
|
||||||
const y = positionArray[intersectIndex * 3 + 1];
|
|
||||||
const z = positionArray[intersectIndex * 3 + 2];
|
|
||||||
|
|
||||||
// 3D-Koordinaten in 2D Bildschirmkoordinaten umrechnen
|
|
||||||
const screenPosition = new THREE.Vector3(x, y, z);
|
|
||||||
screenPosition.project(camera);
|
|
||||||
|
|
||||||
// Umrechnung von NDC (Normalized Device Coordinates) zu Pixeln
|
|
||||||
const tooltipX = (screenPosition.x * 0.5 + 0.5) * window.innerWidth;
|
|
||||||
const tooltipY = (screenPosition.y * -0.5 + 0.5) * window.innerHeight;
|
|
||||||
|
|
||||||
tooltipRef.value.style.left = `${tooltipX + 10}px`; // 10px Abstand zum Punkt
|
|
||||||
tooltipRef.value.style.top = `${tooltipY + 10}px`; // 10px Abstand zum Punkt
|
|
||||||
|
|
||||||
tooltipText.value = `${point.driver.name}: ${point.name} (${point.time.toLocaleString()})`;
|
|
||||||
} else {
|
} else {
|
||||||
tooltipRef.value.style.display = "none";
|
tooltipRef.value.style.display = "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
canvasRef.value.addEventListener("mousemove", onMouseMove);
|
canvasRef.value.addEventListener("mousemove", onMouseMove);
|
||||||
|
|
||||||
@ -237,8 +250,6 @@ export default defineComponent({
|
|||||||
tooltipText,
|
tooltipText,
|
||||||
legend,
|
legend,
|
||||||
driverColors,
|
driverColors,
|
||||||
legend,
|
|
||||||
driverColors,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -261,16 +272,6 @@ export default defineComponent({
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- Legende -->
|
|
||||||
<div class="legend absolute top-10 left-10 bg-base-200 p-4 rounded shadow-lg z-50">
|
|
||||||
<h3 class="font-bold mb-2">Fahrer Legende</h3>
|
|
||||||
<ul>
|
|
||||||
<li v-for="(driverName, driverId) in legend" :key="driverId" class="flex items-center mb-1">
|
|
||||||
<div class="w-4 h-4" :style="{ backgroundColor: driverColors[driverId] }"></div>
|
|
||||||
<span class="ml-2">{{ driverName }}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -323,40 +324,4 @@ export default defineComponent({
|
|||||||
height: 15px;
|
height: 15px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
.tooltip {
|
</style>
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 50;
|
|
||||||
padding: 2px 8px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: white;
|
|
||||||
border-radius: 4px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.legend {
|
|
||||||
width: auto;
|
|
||||||
max-width: 250px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: white;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.legend ul {
|
|
||||||
padding: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.legend li {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.legend .color-box {
|
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -5,7 +5,6 @@ import VueDatePicker from '@vuepic/vue-datepicker';
|
|||||||
import '@vuepic/vue-datepicker/dist/main.css'
|
import '@vuepic/vue-datepicker/dist/main.css'
|
||||||
import Map from '../components/map.vue';
|
import Map from '../components/map.vue';
|
||||||
import FileUpload from '../components/fileUpload.vue';
|
import FileUpload from '../components/fileUpload.vue';
|
||||||
import MapMultiple from '../components/mapMultiple.vue';
|
|
||||||
|
|
||||||
type DriverType = {
|
type DriverType = {
|
||||||
id: number
|
id: number
|
||||||
@ -38,7 +37,7 @@ type GeoJSON = {
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'map',
|
name: 'map',
|
||||||
components: { PointCloud, VueDatePicker, Map, MapMultiple, FileUpload },
|
components: { PointCloud, VueDatePicker, Map, FileUpload },
|
||||||
setup(_, { emit }: SetupContext) {
|
setup(_, { emit }: SetupContext) {
|
||||||
const showMap: Ref<boolean> = ref(false);
|
const showMap: Ref<boolean> = ref(false);
|
||||||
const showCloud: Ref<boolean> = ref(false);
|
const showCloud: Ref<boolean> = ref(false);
|
||||||
@ -50,9 +49,8 @@ export default defineComponent({
|
|||||||
const endSearchDate = ref();
|
const endSearchDate = ref();
|
||||||
const mapData: Ref<GeoJSON | null> = ref(null);
|
const mapData: Ref<GeoJSON | null> = ref(null);
|
||||||
const renderSearchOnMap: Ref<Boolean> = ref(false);
|
const renderSearchOnMap: Ref<Boolean> = ref(false);
|
||||||
const multipleTracks:Ref<Boolean> = ref(false);
|
const multipleTracks: Ref<Boolean> = ref(false);
|
||||||
const trackid: Ref<number> = ref(0)
|
const trackid: Ref<number> = ref(0)
|
||||||
const trackids: Ref<number[]> = ref([])
|
|
||||||
|
|
||||||
const loadTrack = async (id: number) => {
|
const loadTrack = async (id: number) => {
|
||||||
showMap.value = true;
|
showMap.value = true;
|
||||||
@ -118,73 +116,57 @@ export default defineComponent({
|
|||||||
|
|
||||||
showMap.value = false;
|
showMap.value = false;
|
||||||
search.value = false;
|
search.value = false;
|
||||||
|
showCloud.value = true;
|
||||||
showUpload.value = false;
|
showUpload.value = false;
|
||||||
|
multipleTracks.value = false;
|
||||||
|
|
||||||
if (startSearchDate.value == null || endSearchDate.value == null) {
|
if (startSearchDate.value == null || endSearchDate.value == null) {
|
||||||
alert("please give all required infos")
|
alert("please give all required infos")
|
||||||
showCloud.value = false;
|
|
||||||
search.value = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderSearchOnMap.value) {
|
|
||||||
const request: RequestInfo = new Request("http://localhost:5000/track?start=" + startSearchDate.value + "&end=" + endSearchDate.value, {
|
|
||||||
method: "GET",
|
|
||||||
headers: headers
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
var response = await fetch(request);
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
// Wenn die Antwort OK ist, die Daten verarbeiten
|
|
||||||
var resp = await response.json()
|
|
||||||
|
|
||||||
for (let i = 0; i < resp.length; i++) {
|
|
||||||
trackids.value.push(resp[i]["id"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
showMap.value = true;
|
|
||||||
} else {
|
|
||||||
console.log(await response.text());
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Fehler beim Laden der Track-Daten:", error);
|
|
||||||
}
|
|
||||||
showMap.value = true;
|
|
||||||
multipleTracks.value = true;
|
|
||||||
} else {
|
|
||||||
const request: RequestInfo = new Request("http://localhost:5000/track?start=" + startSearchDate.value + "&end=" + endSearchDate.value, {
|
const request: RequestInfo = new Request("http://localhost:5000/track?start=" + startSearchDate.value + "&end=" + endSearchDate.value, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: headers
|
headers: headers
|
||||||
})
|
})
|
||||||
|
|
||||||
var response = await fetch(request)
|
var response = await fetch(request)
|
||||||
// make sure the request was successfull
|
// make sure the request was successfull
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
var jsonBody = await response.json()
|
var jsonBody = await response.json()
|
||||||
console.log(jsonBody)
|
console.log(jsonBody)
|
||||||
searchedTracks.value = [];
|
searchedTracks.value = [];
|
||||||
|
|
||||||
// convert vehicles from json response to processable data
|
// convert vehicles from json response to processable data
|
||||||
for (let i = 0; i < jsonBody.length; i++) {
|
for (let i = 0; i < jsonBody.length; i++) {
|
||||||
let track = jsonBody[i]
|
let track = jsonBody[i]
|
||||||
console.log(`track: ${jsonBody[i]["name"]}`)
|
console.log(`track: ${jsonBody[i]["name"]}`)
|
||||||
searchedTracks.value.push({
|
searchedTracks.value.push({
|
||||||
id: track["id"],
|
id: track["id"],
|
||||||
name: track["name"],
|
name: track["name"],
|
||||||
driver: {
|
driver: {
|
||||||
name: track["driver"]["name"],
|
name: track["driver"]["name"],
|
||||||
id: track["driver"]["id"]
|
id: track["driver"]["id"]
|
||||||
},
|
},
|
||||||
time: track["time"]
|
time: track["time"]
|
||||||
})
|
})
|
||||||
}
|
|
||||||
showCloud.value = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
console.log(await response.text())
|
|
||||||
}
|
}
|
||||||
|
showCloud.value = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log(await response.text())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderSearchOnMap.value) {
|
||||||
|
multipleTracks.value = true;
|
||||||
|
showMap.value = true;
|
||||||
|
showCloud.value = false;
|
||||||
|
|
||||||
|
searchedTracks.value.forEach(async track => {
|
||||||
|
setTimeout(async () => {
|
||||||
|
await loadTrack(track.id);
|
||||||
|
}, 500)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +188,6 @@ export default defineComponent({
|
|||||||
showUpload,
|
showUpload,
|
||||||
multipleTracks,
|
multipleTracks,
|
||||||
trackid,
|
trackid,
|
||||||
trackids
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -226,7 +207,8 @@ export default defineComponent({
|
|||||||
<li>
|
<li>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
</li>
|
</li>
|
||||||
<li v-for="track in tracks"> <a v-on:click="loadTrack(track.id)"> {{ track.name }} </a> </li>
|
<li v-for="track in tracks"> <a v-on:click="loadTrack(track.id); multipleTracks = false;"> {{ track.name }} </a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 70%; margin-left: 5%;">
|
<div style="width: 70%; margin-left: 5%;">
|
||||||
@ -248,11 +230,9 @@ export default defineComponent({
|
|||||||
<button v-on:click="searchTracks" class="btn btn-success"
|
<button v-on:click="searchTracks" class="btn btn-success"
|
||||||
style="margin-left: 5%; height:60px; width:120px;">Search</button>
|
style="margin-left: 5%; height:60px; width:120px;">Search</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!multipleTracks && showMap && !search && !showCloud">
|
<div v-if="showMap && !search && !showCloud">
|
||||||
<Map :track="trackid" :geoJsonData="mapData" style="width: 68vw; margin-left: 10%; border-radius: 10px; border: 1px solid #95a5a6;"></Map>
|
<Map :track="trackid" :multiple="multipleTracks" :geoJsonData="mapData"
|
||||||
</div>
|
style="width: 68vw; margin-left: 10%; border-radius: 10px; border: 1px solid #95a5a6;"></Map>
|
||||||
<div v-if="multipleTracks && showMap && !search && !showCloud">
|
|
||||||
<MapMultiple :tracks="trackids" style="width: 68vw; margin-left: 10%; border-radius: 10px; border: 1px solid #95a5a6;"></MapMultiple>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user