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];