bug fixes, improvements
@@ -7,6 +7,11 @@
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="DeFlock" />
|
||||
<meta property="og:description" content="Your car is being tracked. See where license plate readers are, avoid them, and report new ones. Protect your privacy at Deflock.me." />
|
||||
<meta property="og:image" content="https://deflock.me/og-banner.png" />
|
||||
<meta property="og:url" content="https://deflock.me" />
|
||||
<meta property="og:type" content="website" />
|
||||
<title>DeFlock - ALPR Database</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
BIN
webapp/public/flock-1.jpg
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
webapp/public/flock-2.jpg
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
webapp/public/flock-3.jpg
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
webapp/public/flock-4.jpg
Normal file
|
After Width: | Height: | Size: 159 KiB |
BIN
webapp/public/flock-5.jpg
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
webapp/public/flock-6.jpg
Normal file
|
After Width: | Height: | Size: 253 KiB |
BIN
webapp/public/og-banner.png
Normal file
|
After Width: | Height: | Size: 405 KiB |
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-container max-width="1000">
|
||||
<h2>About Us</h2>
|
||||
<p>
|
||||
Welcome to DeFlock, your go-to resource for understanding and addressing the growing presence of Automated License Plate Readers (ALPRs) in our communities.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-container max-width="1000">
|
||||
<h2>Contact Us</h2>
|
||||
<p>
|
||||
If you have any questions or concerns about the data on this site, please contact us at <a href="mailto:contact@deflock.me">contact@deflock.me</a>.
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
:key="alpr.id"
|
||||
:lat-lng="[alpr.lat, alpr.lon]"
|
||||
><l-popup>
|
||||
<h2>ALPR</h2>
|
||||
<p v-if="alpr.tags.brand || alpr.tags.operator"><strong>Brand: </strong><a target="_blank" :href="`https://www.wikidata.org/wiki/${alpr.tags['brand:wikidata'] || alpr.tags['operator:wikidata']}`">{{ alpr.tags.brand || alpr.tags.operator || 'Unknown' }}</a></p>
|
||||
<p v-if="alpr.tags.direction"><strong>Faces: {{ degreesToCardinal(alpr.tags.direction) }}</strong></p>
|
||||
<p class="mb-0 mt-2" v-if="alpr.tags.brand || alpr.tags.operator"><strong>Brand: </strong><a target="_blank" :href="`https://www.wikidata.org/wiki/${alpr.tags['brand:wikidata'] || alpr.tags['operator:wikidata']}`">{{ alpr.tags.brand || alpr.tags.operator || 'Unknown' }}</a></p>
|
||||
<p class="my-0" v-if="alpr.tags.direction"><strong>Faces: {{ degreesToCardinal(alpr.tags.direction) }} {{ alpr.tags.direction }}°</strong></p>
|
||||
</l-popup></l-marker>
|
||||
</l-map>
|
||||
<div v-else>
|
||||
loading...
|
||||
<div class="loader" v-else>
|
||||
<span class="mb-4 text-grey">Loading Map</span>
|
||||
<v-progress-circular indeterminate color="primary" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -44,7 +44,7 @@ import type { Ref } from 'vue';
|
||||
import { BoundingBox } from '@/services/apiService';
|
||||
import { getALPRs } from '@/services/apiService';
|
||||
|
||||
const zoom: Ref<number> = ref(12);
|
||||
const zoom: Ref<number> = ref(13);
|
||||
const center: Ref<any|null> = ref(null);
|
||||
const bounds: Ref<BoundingBox|null> = ref(null);
|
||||
const router = useRouter();
|
||||
@@ -115,13 +115,15 @@ function updateMarkers() {
|
||||
}
|
||||
|
||||
if (!canRefreshMarkers.value) {
|
||||
console.log('zoomed out too far');
|
||||
return;
|
||||
}
|
||||
|
||||
getALPRs(bounds.value)
|
||||
.then((alprs: any) => {
|
||||
alprsInView.value = alprs.elements;
|
||||
// merge incoming with existing, so that moving the map doesn't remove markers
|
||||
const existingIds = new Set(alprsInView.value.map(alpr => alpr.id));
|
||||
const newAlprs = alprs.elements.filter((alpr: any) => !existingIds.has(alpr.id));
|
||||
alprsInView.value = [...alprsInView.value, ...newAlprs];
|
||||
bboxForLastRequest.value = bounds.value;
|
||||
});
|
||||
}
|
||||
@@ -149,6 +151,10 @@ onMounted(() => {
|
||||
.then(location => {
|
||||
if (!hash)
|
||||
center.value = { lat: location[0], lng: location[1] };
|
||||
}).catch(error => {
|
||||
// TODO: allow search
|
||||
console.debug('Error getting user location. Defaulting to Huntsville, AL.', error);
|
||||
center.value = { lat: 34.730819, lng: -86.586114 }; // Huntsville, AL
|
||||
});
|
||||
});
|
||||
|
||||
@@ -167,10 +173,25 @@ onMounted(() => {
|
||||
bottom: 32px;
|
||||
left: 32px;
|
||||
width: calc(100% - 64px);
|
||||
max-width: 1000px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1000;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.loader {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-container max-width="1000">
|
||||
<v-alert
|
||||
variant="tonal"
|
||||
type="info"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-container max-width="1000">
|
||||
<h1>Feature Roadmap</h1>
|
||||
|
||||
<h2>Current Features</h2>
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<h2>Upcoming Features</h2>
|
||||
<div class="ml-4">
|
||||
<h3><v-icon start>mdi-magnify</v-icon>Search Functionality</h3>
|
||||
<p>
|
||||
Search the map for specific locations, cities, or regions.
|
||||
</p>
|
||||
|
||||
<h3><v-icon start>mdi-map-marker-plus</v-icon>Report an ALPR on this Site</h3>
|
||||
<p>
|
||||
Report ALPRs directly from this site, without having to use the OSM Editor or copy and paste object tags.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-container max-width="1000">
|
||||
<p>
|
||||
<v-img max-height="350" width="100%" cover src="/flock-camera.jpeg" />
|
||||
</p>
|
||||
@@ -31,9 +31,18 @@
|
||||
</div>
|
||||
|
||||
<h2 id="not-alpr" :class="{ highlighted: route.hash === '#not-alpr' }">What They Look Like</h2>
|
||||
<v-img class="my-4" width="400" src="/flock-camera.jpeg" />
|
||||
<v-carousel class="my-4" hide-delimiters>
|
||||
<v-carousel-item
|
||||
v-for="n in carouselCount"
|
||||
:key="n"
|
||||
aspect-ratio="1"
|
||||
:src="`/flock-${n}.jpg`"
|
||||
></v-carousel-item>
|
||||
</v-carousel>
|
||||
|
||||
|
||||
<p>
|
||||
The most common brand of ALPRs in the US is Flock Safety. They are easy to spot because they almost all look the same. They are usually mounted on a standalone black pole with a solar panel on top. The cameras are often placed near intersections or on main roads at the edge of a city or town.
|
||||
The most common brand of ALPRs in the US is <a href="https://en.wikipedia.org/wiki/Flock_Safety" target="_blank">Flock Safety</a>. They are easy to spot because they almost all look the same. They are almost always mounted on a pole with a solar panel on top. In rural areas, they are likely to be on standalone black poles, while in cities, they are more likely to be on existing utility/traffic poles. The cameras are often placed near intersections or on main roads at the edge of a city or town.
|
||||
</p>
|
||||
|
||||
<h2>Not All Cameras are ALPRs</h2>
|
||||
@@ -66,6 +75,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router';
|
||||
const route = useRoute();
|
||||
|
||||
const carouselCount = 6;
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||