a little hacky but it works

This commit is contained in:
Will Freeman
2024-09-30 21:35:40 -05:00
parent acfff6bb40
commit 6d8b3ba42f
7 changed files with 372 additions and 11 deletions
+26
View File
@@ -0,0 +1,26 @@
import axios from "axios";
export interface BoundingBox {
minLat: number;
maxLat: number;
minLng: number;
maxLng: number;
}
const apiService = axios.create({
baseURL: "http://localhost:8080",
headers: {
"Content-Type": "application/json",
},
});
export const getALPRs = async (boundingBox: BoundingBox) => {
const queryParams = new URLSearchParams({
minLat: boundingBox.minLat.toString(),
maxLat: boundingBox.maxLat.toString(),
minLng: boundingBox.minLng.toString(),
maxLng: boundingBox.maxLng.toString(),
});
const response = await apiService.get(`/alpr?${queryParams.toString()}`);
return response.data;
}
+127 -4
View File
@@ -1,12 +1,26 @@
<template>
<div class="map-container">
<!-- use-global-leaflet=false is a workaround for a bug in current version of vue-leaflet -->
<l-map v-if="center" ref="map" v-model:zoom="zoom" :center="center" :use-global-leaflet="false">
<l-map
v-if="center"
ref="map"
v-model:zoom="zoom"
v-model:center="center"
:use-global-leaflet="false"
@update:bounds="updateBounds"
@ready="mapLoaded"
>
<l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
layer-type="base"
name="OpenStreetMap"
></l-tile-layer>
<l-marker
@click="console.log('marker clicked')"
v-for="alpr in alprsInView"
:key="alpr.id"
:lat-lng="[alpr.lat, alpr.lon]"
><l-popup>This is an ALPR! Fuck it!</l-popup></l-marker>
</l-map>
<div v-else>
loading...
@@ -16,12 +30,58 @@
<script setup lang="ts">
import 'leaflet/dist/leaflet.css';
import { LMap, LTileLayer, LMarker } from '@vue-leaflet/vue-leaflet';
import { LMap, LTileLayer, LMarker, LPopup } from '@vue-leaflet/vue-leaflet';
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router'
import type { Ref } from 'vue';
import type { BoundingBox } from '@/services/apiService';
import { getALPRs } from '@/services/apiService';
const zoom: Ref<number> = ref(12);
const center: Ref<[number, number]|null> = ref(null);
const center: Ref<any|null> = ref(null);
const bounds: Ref<BoundingBox|null> = ref(null);
const router = useRouter();
const alprsInView = ref([
{
"type": "node",
"id": 12187369976,
"lat": 34.6616103,
"lon": -86.4870137,
"tags": {
"brand": "Flock Safety",
"brand:wikidata": "Q108485435",
"camera:mount": "pole",
"camera:type": "fixed",
"direction": "335",
"man_made": "surveillance",
"operator": "Flock Safety",
"operator:wikidata": "Q108485435",
"surveillance": "traffic",
"surveillance:type": "ALPR",
"surveillance:zone": "traffic"
}
},
{
"type": "node",
"id": 12187369977,
"lat": 34.6615727,
"lon": -86.4881948,
"tags": {
"brand": "Flock Safety",
"brand:wikidata": "Q108485435",
"camera:mount": "pole",
"camera:type": "fixed",
"direction": "295",
"man_made": "surveillance",
"operator": "Flock Safety",
"operator:wikidata": "Q108485435",
"surveillance": "traffic",
"surveillance:type": "ALPR",
"surveillance:zone": "traffic"
}
}
]);
function getUserLocation(): Promise<[number, number]> {
return new Promise((resolve, reject) => {
@@ -44,10 +104,73 @@ function getUserLocation(): Promise<[number, number]> {
});
};
function mapLoaded(map: any) {
updateBounds(map.getBounds());
}
function updateBounds(newBounds: any) {
bounds.value = {
minLat: newBounds.getSouth(),
maxLat: newBounds.getNorth(),
minLng: newBounds.getWest(),
maxLng: newBounds.getEast(),
};
updateMarkers();
if (center.value) {
updateURL();
}
}
function updateURL() {
if (!center.value) {
return;
}
router.replace({
hash: `#map=${zoom.value}/${center.value.lat.toFixed(6)}/${center.value.lng.toFixed(6)}`
});
}
function updateMarkers() {
// Fetch ALPRs in the current view
if (!bounds.value) {
return;
}
if (zoom.value < 12) {
console.log('zoomed out too far');
return;
}
// getALPRs(bounds.value)
// .then((alprs: any) => {
// alprsInView.value = alprs.elements;
// });
}
onMounted(() => {
const hash = router.currentRoute.value.hash;
if (hash) {
const parts = hash.split('/');
console.log('parts', parts);
if (parts.length === 3 && parts[0].startsWith('#map')) {
const zoomLevelString = parts[0].replace('#map=', '');
zoom.value = parseInt(zoomLevelString, 10);
center.value = {
lat: parseFloat(parts[1]),
lng: parseFloat(parts[2]),
};
console.log('center', center.value);
console.log('zoom', zoom.value);
}
}
getUserLocation()
.then(location => {
center.value = location;
if (!hash)
center.value = { lat: location[0], lng: location[1] };
});
});