diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 1b9e9de..71f74d1 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -17,6 +17,7 @@
"devDependencies": {
"@mdi/font": "^7.4.47",
"@tsconfig/node20": "^20.1.4",
+ "@types/leaflet": "^1.9.15",
"@types/node": "^20.14.5",
"@vitejs/plugin-vue": "^5.0.5",
"@vue-leaflet/vue-leaflet": "^0.10.1",
@@ -25,6 +26,7 @@
"npm-run-all2": "^6.2.0",
"typescript": "~5.4.0",
"vite": "^5.3.1",
+ "vue-leaflet-rotate-marker": "^0.1.0",
"vue-tsc": "^2.0.21"
}
},
@@ -669,6 +671,21 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/geojson": {
+ "version": "7946.0.15",
+ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.15.tgz",
+ "integrity": "sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA==",
+ "dev": true
+ },
+ "node_modules/@types/leaflet": {
+ "version": "1.9.15",
+ "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.15.tgz",
+ "integrity": "sha512-7UuggAuAs+mva66gtf2OTB1nEhzU/9JED93TIaOEgvFMvG/dIGQaukHE7izHo1Zd+Ko1L4ETUw7TBc8yUxevpg==",
+ "dev": true,
+ "dependencies": {
+ "@types/geojson": "*"
+ }
+ },
"node_modules/@types/node": {
"version": "20.16.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.6.tgz",
@@ -1472,6 +1489,15 @@
}
}
},
+ "node_modules/vue-leaflet-rotate-marker": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/vue-leaflet-rotate-marker/-/vue-leaflet-rotate-marker-0.1.0.tgz",
+ "integrity": "sha512-qBrb/ydvl+cuQSZ3cinH2G0nmFNglh5h9qVIFRAlrcjCNqZE1RIEHxwjvxA0CCxdlNFxGeeZy0RFrkdSqNToeg==",
+ "dev": true,
+ "dependencies": {
+ "vue": "^3.3.4"
+ }
+ },
"node_modules/vue-router": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz",
@@ -1872,6 +1898,21 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "@types/geojson": {
+ "version": "7946.0.15",
+ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.15.tgz",
+ "integrity": "sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA==",
+ "dev": true
+ },
+ "@types/leaflet": {
+ "version": "1.9.15",
+ "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.15.tgz",
+ "integrity": "sha512-7UuggAuAs+mva66gtf2OTB1nEhzU/9JED93TIaOEgvFMvG/dIGQaukHE7izHo1Zd+Ko1L4ETUw7TBc8yUxevpg==",
+ "dev": true,
+ "requires": {
+ "@types/geojson": "*"
+ }
+ },
"@types/node": {
"version": "20.16.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.6.tgz",
@@ -2433,6 +2474,15 @@
"@vue/shared": "3.5.8"
}
},
+ "vue-leaflet-rotate-marker": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/vue-leaflet-rotate-marker/-/vue-leaflet-rotate-marker-0.1.0.tgz",
+ "integrity": "sha512-qBrb/ydvl+cuQSZ3cinH2G0nmFNglh5h9qVIFRAlrcjCNqZE1RIEHxwjvxA0CCxdlNFxGeeZy0RFrkdSqNToeg==",
+ "dev": true,
+ "requires": {
+ "vue": "^3.3.4"
+ }
+ },
"vue-router": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz",
diff --git a/webapp/package.json b/webapp/package.json
index c48f62f..490777b 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -20,6 +20,7 @@
"devDependencies": {
"@mdi/font": "^7.4.47",
"@tsconfig/node20": "^20.1.4",
+ "@types/leaflet": "^1.9.15",
"@types/node": "^20.14.5",
"@vitejs/plugin-vue": "^5.0.5",
"@vue-leaflet/vue-leaflet": "^0.10.1",
@@ -28,6 +29,7 @@
"npm-run-all2": "^6.2.0",
"typescript": "~5.4.0",
"vite": "^5.3.1",
+ "vue-leaflet-rotate-marker": "^0.1.0",
"vue-tsc": "^2.0.21"
}
}
diff --git a/webapp/public/map-icon.svg b/webapp/public/map-icon.svg
new file mode 100644
index 0000000..213d7b5
--- /dev/null
+++ b/webapp/public/map-icon.svg
@@ -0,0 +1,10 @@
+
+
+
diff --git a/webapp/src/components/DFMapMarker.vue b/webapp/src/components/DFMapMarker.vue
index eb2f991..4d620b1 100644
--- a/webapp/src/components/DFMapMarker.vue
+++ b/webapp/src/components/DFMapMarker.vue
@@ -1,28 +1,25 @@
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
diff --git a/webapp/src/components/DFMapPopup.vue b/webapp/src/components/DFMapPopup.vue
index aa98f60..0fbb382 100644
--- a/webapp/src/components/DFMapPopup.vue
+++ b/webapp/src/components/DFMapPopup.vue
@@ -5,13 +5,13 @@
mdi-face-recognition Face Recognition
- mdi-car License Plate
+ mdi-cctv License Plate Reader
mdi-adjust Omnidirectional
- mdi-cctv Directional {{ alpr.tags.direction ? `(${degreesToCardinal(parseInt(alpr.tags.direction))})` : '' }}
+ mdi-compass-outline {{ cardinalDirection }}
mdi-domain
@@ -75,6 +75,10 @@ const kvTags = computed(() => {
.map(([key, value]) => ({ key, value: valueTransformations[key]?.(value) ?? value }));
});
+const cardinalDirection = computed(() =>
+ props.alpr.tags.direction === undefined ? 'Unknown' : degreesToCardinal(parseInt(props.alpr.tags.direction))
+);
+
function degreesToCardinal(degrees: number): string {
const cardinals = ['North', 'Northeast', 'East', 'Southeast', 'South', 'Southwest', 'West', 'Northwest'];
return cardinals[Math.round(degrees / 45) % 8];