clickablePoints #1
@@ -49,7 +49,6 @@ try:
|
|||||||
session.flush()
|
session.flush()
|
||||||
except:
|
except:
|
||||||
print("default data not pushed as already present")
|
print("default data not pushed as already present")
|
||||||
session.flush()
|
|
||||||
|
|
||||||
print("initialize handlers")
|
print("initialize handlers")
|
||||||
gpxHandler = GPXHandler(session)
|
gpxHandler = GPXHandler(session)
|
||||||
@@ -278,7 +277,7 @@ def handleVehicleRoute():
|
|||||||
vehicleHandler.deleteVehicle(data["id"])
|
vehicleHandler.deleteVehicle(data["id"])
|
||||||
return "vehicle deleted", 200
|
return "vehicle deleted", 200
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"couldnt delete vehicle due to error: {e}", 500
|
return f"couldn't delete vehicle due to error: {e}", 500
|
||||||
|
|
||||||
|
|
||||||
@app.route('/upload', methods=['POST'])
|
@app.route('/upload', methods=['POST'])
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ services:
|
|||||||
POSTGRES_USER: example
|
POSTGRES_USER: example
|
||||||
POSTGRES_PASSWORD: example
|
POSTGRES_PASSWORD: example
|
||||||
POSTGRES_DB: geotrack
|
POSTGRES_DB: geotrack
|
||||||
|
# volumes:
|
||||||
|
# - ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||||
# web:
|
# web:
|
||||||
# build: .
|
# build: .
|
||||||
# ports:
|
# ports:
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
-- Adminer 4.8.1 PostgreSQL 16.4 (Debian 16.4-1.pgdg120+1) dump
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS "driver";
|
||||||
|
DROP SEQUENCE IF EXISTS driver_id_seq;
|
||||||
|
CREATE SEQUENCE driver_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1;
|
||||||
|
|
||||||
|
CREATE TABLE "public"."driver" (
|
||||||
|
"id" integer DEFAULT nextval('driver_id_seq') NOT NULL,
|
||||||
|
"name" character varying NOT NULL,
|
||||||
|
CONSTRAINT "driver_pkey" PRIMARY KEY ("id")
|
||||||
|
) WITH (oids = false);
|
||||||
|
|
||||||
|
INSERT INTO "driver" ("id", "name") VALUES
|
||||||
|
(1, 'default');
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS "track";
|
||||||
|
DROP SEQUENCE IF EXISTS track_id_seq;
|
||||||
|
CREATE SEQUENCE track_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1;
|
||||||
|
|
||||||
|
CREATE TABLE "public"."track" (
|
||||||
|
"id" integer DEFAULT nextval('track_id_seq') NOT NULL,
|
||||||
|
"trackName" character varying(200),
|
||||||
|
"vehicle_id" integer NOT NULL,
|
||||||
|
"driver_id" integer NOT NULL,
|
||||||
|
"date" date,
|
||||||
|
"distance" double precision NOT NULL,
|
||||||
|
"speed" double precision NOT NULL,
|
||||||
|
CONSTRAINT "track_pkey" PRIMARY KEY ("id")
|
||||||
|
) WITH (oids = false);
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS "vehicle";
|
||||||
|
DROP SEQUENCE IF EXISTS vehicle_id_seq;
|
||||||
|
CREATE SEQUENCE vehicle_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1;
|
||||||
|
|
||||||
|
CREATE TABLE "public"."vehicle" (
|
||||||
|
"id" integer DEFAULT nextval('vehicle_id_seq') NOT NULL,
|
||||||
|
"name" character varying NOT NULL,
|
||||||
|
"licenseplate" character varying,
|
||||||
|
CONSTRAINT "vehicle_pkey" PRIMARY KEY ("id")
|
||||||
|
) WITH (oids = false);
|
||||||
|
|
||||||
|
INSERT INTO "vehicle" ("id", "name", "licenseplate") VALUES
|
||||||
|
(1, 'default', 'default');
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS "waypoint";
|
||||||
|
DROP SEQUENCE IF EXISTS waypoint_id_seq;
|
||||||
|
CREATE SEQUENCE waypoint_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1;
|
||||||
|
|
||||||
|
CREATE TABLE "public"."waypoint" (
|
||||||
|
"id" integer DEFAULT nextval('waypoint_id_seq') NOT NULL,
|
||||||
|
"lat" double precision NOT NULL,
|
||||||
|
"lon" double precision NOT NULL,
|
||||||
|
"ele" double precision NOT NULL,
|
||||||
|
"speed" double precision,
|
||||||
|
"time" timestamp,
|
||||||
|
"track_id" integer NOT NULL,
|
||||||
|
CONSTRAINT "waypoint_pkey" PRIMARY KEY ("id")
|
||||||
|
) WITH (oids = false);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE ONLY "public"."track" ADD CONSTRAINT "track_driver_id_fkey" FOREIGN KEY (driver_id) REFERENCES driver(id) NOT DEFERRABLE;
|
||||||
|
ALTER TABLE ONLY "public"."track" ADD CONSTRAINT "track_vehicle_id_fkey" FOREIGN KEY (vehicle_id) REFERENCES vehicle(id) NOT DEFERRABLE;
|
||||||
|
|
||||||
|
ALTER TABLE ONLY "public"."waypoint" ADD CONSTRAINT "waypoint_track_id_fkey" FOREIGN KEY (track_id) REFERENCES track(id) NOT DEFERRABLE;
|
||||||
|
|
||||||
|
-- 2025-01-16 09:13:38.732525+00
|
||||||
@@ -32,7 +32,7 @@ class GPXHandler:
|
|||||||
for track in self.__gpx.tracks:
|
for track in self.__gpx.tracks:
|
||||||
# sets track name
|
# sets track name
|
||||||
# if no name is found at a track default to using date
|
# if no name is found at a track default to using date
|
||||||
trackName = track.name or f"Track-{datetime.now().isoformat()}" # todo using time.now might end up being misleading and to be reworked
|
trackName = track.name or f"Track-{datetime.now().isoformat()}"
|
||||||
|
|
||||||
# initializes track values
|
# initializes track values
|
||||||
self.startTime = None
|
self.startTime = None
|
||||||
@@ -132,33 +132,6 @@ class GPXHandler:
|
|||||||
|
|
||||||
return track_list
|
return track_list
|
||||||
|
|
||||||
def getTracksInTimeWithGeoData(self, start, end):
|
|
||||||
# Alle Tracks in der Zeitspanne abfragen
|
|
||||||
tracks = self.__dbSession.query(Track).filter(Track.date.between(start, end)).all()
|
|
||||||
|
|
||||||
# Eine Liste von GeoJSON-Features für alle Tracks
|
|
||||||
features = []
|
|
||||||
|
|
||||||
# Für jedes Track-Objekt die Waypoints abfragen und die GeoJSON-Daten generieren
|
|
||||||
for track in tracks:
|
|
||||||
# Waypoints für das Track laden
|
|
||||||
waypoints = track.waypoints # track.waypoints ist bereits korrekt verknüpft
|
|
||||||
|
|
||||||
# Waypoints in GeoJSON-kompatible Koordinaten umwandeln
|
|
||||||
coordinates = [(wp.lon, wp.lat) for wp in waypoints]
|
|
||||||
|
|
||||||
# LineString Feature für das Track erstellen
|
|
||||||
feature = Feature(geometry=LineString(coordinates))
|
|
||||||
features.append(feature)
|
|
||||||
|
|
||||||
# Ein FeatureCollection erstellen, das alle Track-Features enthält
|
|
||||||
feature_collection = FeatureCollection(features)
|
|
||||||
|
|
||||||
# GeoJSON zurückgeben, das von Leaflet verarbeitet werden kann
|
|
||||||
return feature_collection
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getTracksInTime(self, start, end):
|
def getTracksInTime(self, start, end):
|
||||||
tracks = self.__dbSession.query(Track).filter(Track.date.between(start, end)).all()
|
tracks = self.__dbSession.query(Track).filter(Track.date.between(start, end)).all()
|
||||||
|
|
||||||
|
|||||||
+111319
File diff suppressed because it is too large
Load Diff
+107035
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+113739
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -39,7 +39,7 @@ export default defineComponent({
|
|||||||
<template>
|
<template>
|
||||||
<div class="appContainer">
|
<div class="appContainer">
|
||||||
<Navbar></Navbar>
|
<Navbar></Navbar>
|
||||||
<cookiePrompt v-if="showCookiePrompt"></cookiePrompt>
|
<cookiePrompt v-if="showCookiePrompt" @close="showCookiePrompt=false;" style="margin-left:20%;width:90%;"></cookiePrompt>
|
||||||
<RouterView></RouterView>
|
<RouterView></RouterView>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ export default defineComponent({
|
|||||||
setup(_, { emit }: SetupContext) {
|
setup(_, { emit }: SetupContext) {
|
||||||
|
|
||||||
function acceptCookies(){
|
function acceptCookies(){
|
||||||
|
emit("close")
|
||||||
localStorage.setItem("allow-data-storage", "true")
|
localStorage.setItem("allow-data-storage", "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
function rejectCookies(){
|
function rejectCookies(){
|
||||||
|
emit("close")
|
||||||
localStorage.setItem("allow-data-storage", "false")
|
localStorage.setItem("allow-data-storage", "false")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ export default defineComponent({
|
|||||||
drivers.value.push({ id: jsonBody[i]["id"], name: jsonBody[i]["name"] })
|
drivers.value.push({ id: jsonBody[i]["id"], name: jsonBody[i]["name"] })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert(`upload failed: ${await response.text()}`)
|
||||||
console.log(await response.text())
|
console.log(await response.text())
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `upload failed: ${await response.statusText}`;
|
message.value = `upload failed: ${await response.statusText}`;
|
||||||
@@ -98,8 +100,8 @@ export default defineComponent({
|
|||||||
headers: headers
|
headers: headers
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// make sure the request was successful
|
||||||
var response = await fetch(request)
|
var response = await fetch(request)
|
||||||
// make sure the request was successfull
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
var jsonBody = await response.json()
|
var jsonBody = await response.json()
|
||||||
|
|
||||||
@@ -108,6 +110,8 @@ export default defineComponent({
|
|||||||
vehicles.value.push({ id: jsonBody[i]["id"], name: jsonBody[i]["name"] })
|
vehicles.value.push({ id: jsonBody[i]["id"], name: jsonBody[i]["name"] })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert(`upload failed: ${await response.text()}`)
|
||||||
console.log(await response.text())
|
console.log(await response.text())
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `upload failed: ${await response.text()}`;
|
message.value = `upload failed: ${await response.text()}`;
|
||||||
@@ -118,6 +122,8 @@ export default defineComponent({
|
|||||||
var save = async () => {
|
var save = async () => {
|
||||||
|
|
||||||
if (!file.value) {
|
if (!file.value) {
|
||||||
|
|
||||||
|
alert("please select a file");
|
||||||
messageType.value = "warning";
|
messageType.value = "warning";
|
||||||
message.value = "please select a file";
|
message.value = "please select a file";
|
||||||
return;
|
return;
|
||||||
@@ -142,19 +148,25 @@ export default defineComponent({
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
emit("response", result);
|
emit("response", result);
|
||||||
|
|
||||||
messageType.value = "success";
|
messageType.value = "success";
|
||||||
message.value = `upload successfull`;
|
message.value = `Upload Successful`;
|
||||||
buttonText.value = 'upload successfull';
|
buttonText.value = 'Upload Successful';
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
buttonText.value = "Upload";
|
buttonText.value = "Upload";
|
||||||
}, 2000);
|
}, 2000);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert(`upload failed: ${await response.statusText}`)
|
||||||
console.error('upload failed: ', await response.statusText);
|
console.error('upload failed: ', await response.statusText);
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `upload failed: ${await response.statusText}`;
|
message.value = `upload failed: ${await response.statusText}`;
|
||||||
buttonText.value = "Upload";
|
buttonText.value = "Upload";
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
|
alert(`upload failed: ${error}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `upload failed: ${error}`;
|
message.value = `upload failed: ${error}`;
|
||||||
buttonText.value = "Upload";
|
buttonText.value = "Upload";
|
||||||
|
|||||||
@@ -96,8 +96,10 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
console.log(track.value)
|
console.log(track.value)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert(`failed to load track meta with error: ${await response.statusText}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `"failed to load track meta with error: ${await response.statusText}`;
|
message.value = `failed to load track meta with error: ${await response.statusText}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +124,8 @@ export default defineComponent({
|
|||||||
const bounds = geoJsonLayer.getBounds();
|
const bounds = geoJsonLayer.getBounds();
|
||||||
mapInstance.value.fitBounds(bounds);
|
mapInstance.value.fitBounds(bounds);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert("Map or GeoJSON data not available.")
|
||||||
console.error("Map or GeoJSON data not available.");
|
console.error("Map or GeoJSON data not available.");
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `"Map or GeoJSON data not available.`;
|
message.value = `"Map or GeoJSON data not available.`;
|
||||||
@@ -160,7 +164,9 @@ export default defineComponent({
|
|||||||
<tbody>
|
<tbody>
|
||||||
<!-- row 1 -->
|
<!-- row 1 -->
|
||||||
<tr v-if="track.id == 0" class="bg-base-200">
|
<tr v-if="track.id == 0" class="bg-base-200">
|
||||||
<th>{{ track.name }}</th>
|
<th>
|
||||||
|
<div class="skeleton h-4 w-full"></div>
|
||||||
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<div class="skeleton h-4 w-full"></div>
|
<div class="skeleton h-4 w-full"></div>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -25,19 +25,19 @@ export default defineComponent({
|
|||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="type==='info'" role="alert" class="alert alert-info alert-soft">
|
<div v-if="type=='info'" role="alert" class="alert alert-info alert-soft">
|
||||||
<span>{{ message }}</span>
|
<span>{{ message }}</span>
|
||||||
<button class="btn btn-soft btn-info" v-on:click="close">Close</button>
|
<button class="btn btn-soft btn-info" v-on:click="close">Close</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="type==='success'" role="alert" class="alert alert-success alert-soft">
|
<div v-if="type=='success'" role="alert" class="alert alert-success alert-soft">
|
||||||
<span>{{ message }}</span>
|
<span>{{ message }}</span>
|
||||||
<button class="btn btn-soft btn-success" v-on:click="close">Close</button>
|
<button class="btn btn-soft btn-success" v-on:click="close">Close</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="type==='warning'" role="alert" class="alert alert-warning alert-soft">
|
<div v-if="type=='warning'" role="alert" class="alert alert-warning alert-soft">
|
||||||
<span>{{ message }}</span>
|
<span>{{ message }}</span>
|
||||||
<button class="btn btn-soft btn-warning" v-on:click="close">Close</button>
|
<button class="btn btn-soft btn-warning" v-on:click="close">Close</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="type==='error'" role="alert" class="alert error alert-soft">
|
<div v-if="type=='error'" role="alert" class="alert error alert-soft">
|
||||||
<span>{{ message }}</span>
|
<span>{{ message }}</span>
|
||||||
<button class="btn btn-soft btn-error" v-on:click="close">Close</button>
|
<button class="btn btn-soft btn-error" v-on:click="close">Close</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
console.log(props)
|
console.log(props)
|
||||||
if (!props.routes || props.routes.length <= 0) {
|
if (!props.routes || props.routes.length <= 0) {
|
||||||
|
|
||||||
|
alert("no points to show")
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `no points to show`;
|
message.value = `no points to show`;
|
||||||
}
|
}
|
||||||
@@ -80,6 +82,8 @@ export default defineComponent({
|
|||||||
legend.value[driver["id"]] = driver["name"];
|
legend.value[driver["id"]] = driver["name"];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert(`failed to get drivers with error: ${await response.statusText}`)
|
||||||
console.log(await response.text())
|
console.log(await response.text())
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `failed to get drivers with error: ${await response.statusText}`;
|
message.value = `failed to get drivers with error: ${await response.statusText}`;
|
||||||
@@ -253,7 +257,30 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles mouse clicks to navigate to the specific track page
|
||||||
|
* @param event MouseEvent triggered on click
|
||||||
|
*/
|
||||||
|
const onMouseClick = (event: MouseEvent) => {
|
||||||
|
if (!canvasRef.value) return;
|
||||||
|
|
||||||
|
raycaster.setFromCamera(mouse, camera);
|
||||||
|
const intersects = raycaster.intersectObject(pointCloud);
|
||||||
|
|
||||||
|
if (intersects.length > 0) {
|
||||||
|
const intersectIndex = Math.floor(intersects[0].index || 0);
|
||||||
|
const point = points[intersectIndex];
|
||||||
|
|
||||||
|
console.log(point.id)
|
||||||
|
|
||||||
|
// Redirect to /track/:id using Vue Router
|
||||||
|
router.push(`/route/${point.id}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add event listeners for mouse actions
|
||||||
canvasRef.value.addEventListener("mousemove", onMouseMove);
|
canvasRef.value.addEventListener("mousemove", onMouseMove);
|
||||||
|
canvasRef.value.addEventListener("click", onMouseClick);
|
||||||
|
|
||||||
// Fenstergröße anpassen
|
// Fenstergröße anpassen
|
||||||
window.addEventListener("resize", () => {
|
window.addEventListener("resize", () => {
|
||||||
@@ -278,7 +305,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Message v-if="type != 'None'" :type="messageType" :message="message" @close="message = ''; messageType = 'None'" style="z-index: -1;"></Message>
|
<Message v-if="type != 'None'" :type="messageType" :message="message" @close="message = ''; messageType = 'None'"
|
||||||
|
style="z-index: -1;"></Message>
|
||||||
<div class="pointcloud-container relative">
|
<div class="pointcloud-container relative">
|
||||||
<canvas ref="canvasRef"></canvas>
|
<canvas ref="canvasRef"></canvas>
|
||||||
<div ref="tooltipRef" class="tooltip hidden fixed z-50 px-2 py-1 bg-base-200 text-base-content rounded">
|
<div ref="tooltipRef" class="tooltip hidden fixed z-50 px-2 py-1 bg-base-200 text-base-content rounded">
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default defineComponent({
|
|||||||
const driverList: Ref<driver[]> = ref([])
|
const driverList: Ref<driver[]> = ref([])
|
||||||
|
|
||||||
// values for UI Information distribution
|
// values for UI Information distribution
|
||||||
const messageType: Ref<string> = ref("");
|
const messageType: Ref<string> = ref("error");
|
||||||
const message: Ref<string> = ref("");
|
const message: Ref<string> = ref("");
|
||||||
|
|
||||||
// handles delete a driver
|
// handles delete a driver
|
||||||
@@ -33,13 +33,17 @@ export default defineComponent({
|
|||||||
|
|
||||||
var response = await fetch(request)
|
var response = await fetch(request)
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert(`deleting driver failed with error: ${await response.text()}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `deleting driver failed with error: ${await response.text()}`;
|
message.value = `deleting driver failed with error: ${await response.text()}`;
|
||||||
} else {
|
} else {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert("deleted driver successful")
|
||||||
messageType.value = "success";
|
messageType.value = "success";
|
||||||
message.value = `deleted driver`;
|
message.value = `deleted driver`;
|
||||||
|
driverList.value = []
|
||||||
|
getDrivers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +72,8 @@ export default defineComponent({
|
|||||||
driverList.value.push({ id: jsonBody[i]["id"], name: jsonBody[i]["name"] })
|
driverList.value.push({ id: jsonBody[i]["id"], name: jsonBody[i]["name"] })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert(`upload failed: ${response.text()}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `upload failed: ${response.text()}`;
|
message.value = `upload failed: ${response.text()}`;
|
||||||
}
|
}
|
||||||
@@ -95,9 +100,10 @@ export default defineComponent({
|
|||||||
var jsonBody = await response.json()
|
var jsonBody = await response.json()
|
||||||
driverList.value.push({ id: jsonBody["body"], name: driverName.value })
|
driverList.value.push({ id: jsonBody["body"], name: driverName.value })
|
||||||
} else {
|
} else {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert(`creating driver: ${response.text()}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `upload failed: ${response.text()}`;
|
message.value = `creating driver: ${response.text()}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,8 +122,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Message v-if="type == 'none'" :type="messageType" :message="message" @close="message = ''; messageType = 'None'">
|
<Message v-if="messageType != 'None'" :type="messageType" :message="message" @close="message = ''; messageType = 'None'"></Message>
|
||||||
</Message>
|
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<!-- head -->
|
<!-- head -->
|
||||||
@@ -133,7 +138,9 @@ export default defineComponent({
|
|||||||
<td></td>
|
<td></td>
|
||||||
<td><input type="text" placeholder="Driver Name" class="input input-bordered w-full" v-model="driverName" />
|
<td><input type="text" placeholder="Driver Name" class="input input-bordered w-full" v-model="driverName" />
|
||||||
</td>
|
</td>
|
||||||
<td><a class="btn btn-success w-full" v-on:click="createDriver">Create Driver</a></td>
|
<td><a class="btn btn-success w-full" v-on:click="createDriver"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-lg" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2"/>
|
||||||
|
</svg> Create Driver</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="driverList.length == 0">
|
<tr v-if="driverList.length == 0">
|
||||||
<th>
|
<th>
|
||||||
|
|||||||
+45
-18
@@ -1,11 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, Ref, SetupContext } from 'vue';
|
import { defineComponent, ref, Ref, SetupContext, watch } from 'vue';
|
||||||
import PointCloud from '../components/pointcloud.vue';
|
import PointCloud from '../components/pointcloud.vue';
|
||||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
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 Message from '../components/message.vue';
|
import Message from '../components/message.vue';
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
type DriverType = {
|
type DriverType = {
|
||||||
id: number
|
id: number
|
||||||
@@ -52,16 +53,22 @@ export default defineComponent({
|
|||||||
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 isLoading:Ref<boolean> = ref(false);
|
||||||
|
|
||||||
// values for UI Information distribution
|
// values for UI Information distribution
|
||||||
const messageType: Ref<string> = ref("");
|
const messageType: Ref<string> = ref("");
|
||||||
const message: Ref<string> = ref("");
|
const message: Ref<string> = ref("");
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
watch(() => route.params.id, (id) => {
|
||||||
|
loadTrack(id)
|
||||||
|
})
|
||||||
|
|
||||||
const loadTrack = async (id: number) => {
|
const loadTrack = async (id: number) => {
|
||||||
showMap.value = true;
|
|
||||||
showCloud.value = false;
|
showCloud.value = false;
|
||||||
search.value = false;
|
search.value = false;
|
||||||
showUpload.value = false;
|
showUpload.value = false;
|
||||||
|
isLoading.value = true;
|
||||||
|
|
||||||
trackid.value = id
|
trackid.value = id
|
||||||
|
|
||||||
@@ -78,14 +85,20 @@ export default defineComponent({
|
|||||||
var response = await fetch(request);
|
var response = await fetch(request);
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
// Wenn die Antwort OK ist, die Daten verarbeiten
|
showMap.value = true;
|
||||||
|
isLoading.value = false;
|
||||||
mapData.value = await response.json();
|
mapData.value = await response.json();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert(`loading tracks failed: ${await response.text()}`)
|
||||||
|
isLoading.value = false;
|
||||||
console.log(await response.text());
|
console.log(await response.text());
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `loading tracks failed: ${await response.text()}`;
|
message.value = `loading tracks failed: ${await response.text()}`;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
|
alert(`loading tracks failed with error: ${error}`)
|
||||||
console.error("loading tracks failed with error:", error);
|
console.error("loading tracks failed with error:", error);
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `loading tracks failed with error: ${error}`;
|
message.value = `loading tracks failed with error: ${error}`;
|
||||||
@@ -114,6 +127,8 @@ export default defineComponent({
|
|||||||
message.value = `deleting track failed with error: ${await response.text()}`;
|
message.value = `deleting track failed with error: ${await response.text()}`;
|
||||||
getTracks()
|
getTracks()
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert("deleted track")
|
||||||
console.log(await response.text())
|
console.log(await response.text())
|
||||||
messageType.value = "success";
|
messageType.value = "success";
|
||||||
message.value = `deleted track`;
|
message.value = `deleted track`;
|
||||||
@@ -141,6 +156,8 @@ export default defineComponent({
|
|||||||
tracks.value.push({ id: jsonBody[i]["id"], name: jsonBody[i]["name"], driver: { name: "", id: 0 }, time: new Date(Date.now()) })
|
tracks.value.push({ id: jsonBody[i]["id"], name: jsonBody[i]["name"], driver: { name: "", id: 0 }, time: new Date(Date.now()) })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
alert(`loading track list failed with error: ${error}`)
|
||||||
console.log(await response.text())
|
console.log(await response.text())
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `loading track list failed with error: ${error}`;
|
message.value = `loading track list failed with error: ${error}`;
|
||||||
@@ -151,7 +168,7 @@ export default defineComponent({
|
|||||||
const headers: Headers = new Headers()
|
const headers: Headers = new Headers()
|
||||||
headers.set('Content-Type', 'application/json')
|
headers.set('Content-Type', 'application/json')
|
||||||
headers.set('Accept', 'application/json')
|
headers.set('Accept', 'application/json')
|
||||||
|
isLoading.value = true;
|
||||||
showMap.value = false;
|
showMap.value = false;
|
||||||
search.value = false;
|
search.value = false;
|
||||||
showCloud.value = true;
|
showCloud.value = true;
|
||||||
@@ -190,16 +207,19 @@ export default defineComponent({
|
|||||||
time: track["time"]
|
time: track["time"]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
isLoading.value = false;
|
||||||
showCloud.value = true;
|
showCloud.value = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert(`searching tracks failed: ${await response.text()}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `searching tracks failed: ${await response.text()}`;
|
message.value = `searching tracks failed: ${await response.text()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderSearchOnMap.value) {
|
if (renderSearchOnMap.value) {
|
||||||
multipleTracks.value = true;
|
multipleTracks.value = true;
|
||||||
|
isLoading.value = true;
|
||||||
showMap.value = true;
|
showMap.value = true;
|
||||||
showCloud.value = false;
|
showCloud.value = false;
|
||||||
|
|
||||||
@@ -208,6 +228,8 @@ export default defineComponent({
|
|||||||
await loadTrack(track.id);
|
await loadTrack(track.id);
|
||||||
}, 500)
|
}, 500)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +254,8 @@ export default defineComponent({
|
|||||||
message,
|
message,
|
||||||
messageType,
|
messageType,
|
||||||
deleteTrack,
|
deleteTrack,
|
||||||
getTracks
|
getTracks,
|
||||||
|
isLoading
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -242,8 +265,8 @@ export default defineComponent({
|
|||||||
<template>
|
<template>
|
||||||
<Message v-if="type == 'none'" :type="messageType" :message="message" @close="message = ''; messageType = 'None'">
|
<Message v-if="type == 'none'" :type="messageType" :message="message" @close="message = ''; messageType = 'None'">
|
||||||
</Message>
|
</Message>
|
||||||
<FileUpload v-if="showUpload" @close="showUpload = false;" @response="getTracks" :drivers="[]"
|
<FileUpload v-if="showUpload" @close="showUpload = false;" @response="tracks=[]; getTracks();" :drivers="[]"
|
||||||
style="position:absolute; top: 30VH; width: 80%;"></FileUpload>
|
style="position:absolute; top: 30VH; width: 60%; left:25%;"></FileUpload>
|
||||||
<div class="grid grid-flow-col auto-cols-max gap-4">
|
<div class="grid grid-flow-col auto-cols-max gap-4">
|
||||||
<div>
|
<div>
|
||||||
<ul class="menu menu-xs bg-base-200 rounded-lg w-full max-w-xs overscroll-auto">
|
<ul class="menu menu-xs bg-base-200 rounded-lg w-full max-w-xs overscroll-auto">
|
||||||
@@ -258,18 +281,22 @@ export default defineComponent({
|
|||||||
<div class="skeleton h-4 w-full"></div>
|
<div class="skeleton h-4 w-full"></div>
|
||||||
</li>
|
</li>
|
||||||
<li v-for="track in tracks">
|
<li v-for="track in tracks">
|
||||||
<span><a v-on:click="loadTrack(track.id); multipleTracks = false;"> {{ track.name }}</a>
|
<span><a style="line-height: 50px; height:50px;" v-on:click="loadTrack(track.id); multipleTracks = false; showMap=false;"> {{ track.name }}</a>
|
||||||
<button class="btn btn-error" v-on:click="deleteTrack(track.id)">
|
<button style="width:50px; float:right;" class="btn btn-error" v-on:click="deleteTrack(track.id); tracks=[]; getTracks();">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
||||||
class="bi bi-trash3-fill" viewBox="0 0 16 16">
|
class="bi bi-trash3-fill" viewBox="0 0 16 16">
|
||||||
<path
|
<path
|
||||||
d="M11 1.5v1h3.5a.5.5 0 0 1 0 1h-.538l-.853 10.66A2 2 0 0 1 11.115 16h-6.23a2 2 0 0 1-1.994-1.84L2.038 3.5H1.5a.5.5 0 0 1 0-1H5v-1A1.5 1.5 0 0 1 6.5 0h3A1.5 1.5 0 0 1 11 1.5m-5 0v1h4v-1a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5M4.5 5.029l.5 8.5a.5.5 0 1 0 .998-.06l-.5-8.5a.5.5 0 1 0-.998.06m6.53-.528a.5.5 0 0 0-.528.47l-.5 8.5a.5.5 0 0 0 .998.058l.5-8.5a.5.5 0 0 0-.47-.528M8 4.5a.5.5 0 0 0-.5.5v8.5a.5.5 0 0 0 1 0V5a.5.5 0 0 0-.5-.5" />
|
d="M11 1.5v1h3.5a.5.5 0 0 1 0 1h-.538l-.853 10.66A2 2 0 0 1 11.115 16h-6.23a2 2 0 0 1-1.994-1.84L2.038 3.5H1.5a.5.5 0 0 1 0-1H5v-1A1.5 1.5 0 0 1 6.5 0h3A1.5 1.5 0 0 1 11 1.5m-5 0v1h4v-1a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5M4.5 5.029l.5 8.5a.5.5 0 1 0 .998-.06l-.5-8.5a.5.5 0 1 0-.998.06m6.53-.528a.5.5 0 0 0-.528.47l-.5 8.5a.5.5 0 0 0 .998.058l.5-8.5a.5.5 0 0 0-.47-.528M8 4.5a.5.5 0 0 0-.5.5v8.5a.5.5 0 0 0 1 0V5a.5.5 0 0 0-.5-.5" />
|
||||||
</svg>
|
</svg>
|
||||||
</button></span>
|
</button>
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 70%; margin-left: 5%;">
|
<div v-if="isLoading">
|
||||||
|
<h1 class="title text-center " style="text-align: center;"> map is loading: <span class="loading loading-spinner loading-lg"></span> </h1>
|
||||||
|
</div>
|
||||||
|
<div style="width: 65%; margin-left: 5%;">
|
||||||
<PointCloud :routes="searchedTracks" style="border-radius: 10px;" v-if="showCloud && !search"></PointCloud>
|
<PointCloud :routes="searchedTracks" style="border-radius: 10px;" v-if="showCloud && !search"></PointCloud>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!showMap && !showCloud && search" style="margin-left: 20%; display:flex;">
|
<div v-if="!showMap && !showCloud && search" style="margin-left: 20%; display:flex;">
|
||||||
@@ -290,7 +317,7 @@ export default defineComponent({
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="showMap && !search && !showCloud">
|
<div v-if="showMap && !search && !showCloud">
|
||||||
<Map :track="trackid" :multiple="multipleTracks" :geoJsonData="mapData"
|
<Map :track="trackid" :multiple="multipleTracks" :geoJsonData="mapData"
|
||||||
style="width: 68vw; margin-left: 10%; border-radius: 10px; border: 1px solid #95a5a6;"></Map>
|
style="width: 68vw; margin-left: 15%; border-radius: 10px; border: 1px solid #95a5a6;"></Map>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -35,11 +35,13 @@ export default defineComponent({
|
|||||||
|
|
||||||
var response = await fetch(request)
|
var response = await fetch(request)
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert(`deleting vehicle failed with error: ${await response.text()}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `deleting vehicle failed with error: ${await response.text()}`;
|
message.value = `deleting vehicle failed with error: ${await response.text()}`;
|
||||||
} else {
|
} else {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert("delete vehicle")
|
||||||
messageType.value = "success";
|
messageType.value = "success";
|
||||||
message.value = `deleted vehicle`;
|
message.value = `deleted vehicle`;
|
||||||
}
|
}
|
||||||
@@ -72,7 +74,8 @@ export default defineComponent({
|
|||||||
vehicleList.value.push({ id: vehicle["id"], name: vehicle["name"], licenseplate: plate })
|
vehicleList.value.push({ id: vehicle["id"], name: vehicle["name"], licenseplate: plate })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert(`loading vehicles failed with error: ${await response.text()}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `loading vehicles failed with error: ${await response.text()}`;
|
message.value = `loading vehicles failed with error: ${await response.text()}`;
|
||||||
}
|
}
|
||||||
@@ -99,7 +102,8 @@ export default defineComponent({
|
|||||||
var jsonBody = await response.json()
|
var jsonBody = await response.json()
|
||||||
vehicleList.value.push({ id: jsonBody["body"], name: vehicleName.value, licenseplate: "N/A" })
|
vehicleList.value.push({ id: jsonBody["body"], name: vehicleName.value, licenseplate: "N/A" })
|
||||||
} else {
|
} else {
|
||||||
console.log(await response.text())
|
|
||||||
|
alert(`creating vehicle failed with error: ${error}`)
|
||||||
messageType.value = "error";
|
messageType.value = "error";
|
||||||
message.value = `creating vehicle failed with error: ${error}`;
|
message.value = `creating vehicle failed with error: ${error}`;
|
||||||
}
|
}
|
||||||
@@ -140,7 +144,9 @@ export default defineComponent({
|
|||||||
v-model="vehicleName" /></td>
|
v-model="vehicleName" /></td>
|
||||||
<td><input type="text" placeholder="License Plate" class="input input-bordered w-full "
|
<td><input type="text" placeholder="License Plate" class="input input-bordered w-full "
|
||||||
v-model="licensePlate" /></td>
|
v-model="licensePlate" /></td>
|
||||||
<td><a class="btn btn-success w-full" v-on:click="createVehicle">Create Vehicle</a></td>
|
<td><a class="btn btn-success w-full" v-on:click="createVehicle"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-lg" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2"/>
|
||||||
|
</svg> Create Vehicle</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="vehicleList.length == 0">
|
<tr v-if="vehicleList.length == 0">
|
||||||
<th>
|
<th>
|
||||||
|
|||||||
Reference in New Issue
Block a user