diff --git a/src/components/Map.vue b/src/components/Map.vue
index a7f2be5..1d51801 100644
--- a/src/components/Map.vue
+++ b/src/components/Map.vue
@@ -2,7 +2,12 @@
-
+
+
+
+
+
+
@@ -14,6 +19,8 @@ import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
import iconUrl from 'leaflet/dist/images/marker-icon.png';
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
+import { EARTH_RADIUS } from '@/constants';
+
// Fix for a bug in Leaflet default icon
// see https://github.com/PaulLeCam/react-leaflet/issues/255#issuecomment-261904061
delete L.Icon.Default.prototype._getIconUrl;
@@ -26,24 +33,46 @@ L.Icon.Default.mergeOptions({
export const DEFAULT_ZOOM = 17;
export const MIN_ZOOM = 15;
export const MAX_ZOOM = 18;
-export const TILE_SERVER = process.env.TILE_SERVER || 'https://a.tile.thunderforest.com/cycle/{z}/{x}/{y}.png';
+export const TILE_SERVER = process.env.TILE_SERVER || 'https://a.tile.thunderforest.com/cycle/{z}/{x}/{y}.png';
export default {
props: {
+ accuracy: {
+ type: Number,
+ default: null,
+ },
heading: Number,
lat: Number,
lng: Number,
markers: Array,
},
computed: {
+ radiusFromAccuracy() {
+ if (this.accuracy) {
+ return this.accuracy / (
+ (EARTH_RADIUS * 2 * Math.PI * Math.cos(this.lat)) /
+ (2 ** (this.zoom + 8))
+ );
+ }
+ return null;
+ },
+ shouldDisplayAccuracy() {
+ return (
+ this.accuracy &&
+ this.accuracy < 100 &&
+ this.radiusFromAccuracy > this.markerRadius
+ );
+ },
latlng() {
return [this.lat, this.lng];
},
markerOptions() {
return {
fillColor: '#00ff00',
+ color: '#000000',
heading: this.heading,
+ weight: 1,
};
},
},
@@ -51,6 +80,7 @@ export default {
return {
attribution: 'Map data © OpenStreetMap contributors',
zoom: DEFAULT_ZOOM,
+ markerRadius: 10.0,
minZoom: MIN_ZOOM,
maxZoom: MAX_ZOOM,
tileServer: TILE_SERVER,
diff --git a/src/constants.js b/src/constants.js
new file mode 100644
index 0000000..4ae0182
--- /dev/null
+++ b/src/constants.js
@@ -0,0 +1,6 @@
+export const MOCK_LOCATION = false;
+export const MOCK_LOCATION_UPDATE_INTERVAL = 30 * 1000;
+
+export const UPDATE_REPORTS_DISTANCE_THRESHOLD = 500;
+
+export const EARTH_RADIUS = 6378137;
diff --git a/src/i18n/en.js b/src/i18n/en.js
index 74e13ba..641c193 100644
--- a/src/i18n/en.js
+++ b/src/i18n/en.js
@@ -1,7 +1,7 @@
// Keys should be sorted alphabetically
export default {
geolocation: {
- enable: 'Please accept the geolocation permission request to use the app.',
+ fetching: 'Fetching current position…',
unavailable: 'Sorry, geolocation is not available in your browser.',
},
menu: {
diff --git a/src/main.js b/src/main.js
index 19237cd..1131e70 100644
--- a/src/main.js
+++ b/src/main.js
@@ -19,6 +19,8 @@ Vue.use(Vuetify);
Vue.component('v-lmap', Vue2Leaflet.LMap);
Vue.component('v-ltilelayer', Vue2Leaflet.LTileLayer);
Vue.component('v-lmarker', Vue2Leaflet.LMarker);
+Vue.component('v-lcirclemarker', Vue2Leaflet.LCircleMarker);
+Vue.component('v-lcircle', Vue2Leaflet.LCircle);
Vue.component('v-lpolyline', Vue2Leaflet.LPolyline);
Vue.component('v-lts', Vue2LeafletTracksymbol);
diff --git a/src/tools/index.js b/src/tools/index.js
index 999bcb0..2c7bc37 100644
--- a/src/tools/index.js
+++ b/src/tools/index.js
@@ -1,3 +1,5 @@
+import { EARTH_RADIUS } from '@/constants';
+
export function distance(latLng1, latLng2) {
const lat1 = (latLng1[0] * Math.PI) / 180;
const lng1 = (latLng1[1] * Math.PI) / 180;
@@ -10,7 +12,6 @@ export function distance(latLng1, latLng2) {
(Math.cos(lat1) * Math.cos(lat2) * (Math.sin((lng2 - lng1) / 2.0) ** 2))
);
const c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
- const EARTH_RADIUS = 6371000;
return EARTH_RADIUS * c;
}
@@ -22,9 +23,10 @@ export function mockLocation() {
const LNG_MAX = 2.392742;
return {
coords: {
+ accuracy: 10, // In meters
latitude: (Math.random() * (LAT_MAX - LAT_MIN)) + LAT_MIN,
longitude: (Math.random() * (LNG_MAX - LNG_MIN)) + LNG_MIN,
- heading: 20 * (Math.PI / 180),
+ heading: null, // 20 * (Math.PI / 180),
},
};
}
diff --git a/src/views/Map.vue b/src/views/Map.vue
index b76e9da..7daaf12 100644
--- a/src/views/Map.vue
+++ b/src/views/Map.vue
@@ -2,7 +2,7 @@
-
+
- {{ error }}
-
- Retry
-
+
+ {{ error }}
+
+ Retry
+
+
+
+ {{ $t('geolocation.fetching') }}
+
@@ -32,12 +37,9 @@ import NoSleep from 'nosleep.js';
import Map from '@/components/Map.vue';
import ReportDialog from '@/components/ReportDialog/index.vue';
+import * as constants from '@/constants';
import { distance, mockLocation } from '@/tools';
-const MOCK_LOCATION = false;
-const MOCK_LOCATION_UPDATE_INTERVAL = 30 * 1000;
-const UPDATE_REPORTS_DISTANCE_THRESHOLD = 500;
-
export default {
components: {
Map,
@@ -62,8 +64,9 @@ export default {
},
data() {
return {
+ accuracy: null,
dialog: false,
- error: this.$t('geolocation.enable'),
+ error: null,
heading: null,
lat: null,
lng: null,
@@ -75,11 +78,11 @@ export default {
initializePositionWatching() {
this.disablePositionWatching(); // Ensure at most one at the same time
- if (MOCK_LOCATION) {
+ if (constants.MOCK_LOCATION) {
this.setPosition(mockLocation());
this.watchID = setInterval(
() => this.setPosition(mockLocation()),
- MOCK_LOCATION_UPDATE_INTERVAL,
+ constants.MOCK_LOCATION_UPDATE_INTERVAL,
);
} else {
if (!('geolocation' in navigator)) {
@@ -99,7 +102,7 @@ export default {
},
disablePositionWatching() {
if (this.watchID !== null) {
- if (MOCK_LOCATION) {
+ if (constants.MOCK_LOCATION) {
clearInterval(this.watchID);
} else {
navigator.geolocation.clearWatch(this.watchID);
@@ -115,17 +118,14 @@ export default {
[this.lat, this.lng],
[position.coords.latitude, position.coords.longitude],
);
- if (distanceFromPreviousPoint > UPDATE_REPORTS_DISTANCE_THRESHOLD) {
+ if (distanceFromPreviousPoint > constants.UPDATE_REPORTS_DISTANCE_THRESHOLD) {
this.$store.dispatch('fetchReports');
}
}
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
- if (position.coords.heading) {
- this.heading = position.coords.heading;
- } else {
- this.heading = null;
- }
+ this.heading = position.coords.heading ? position.coords.heading : null;
+ this.accuracy = position.coords.accuracy ? position.coords.accuracy : null;
},
setNoSleep() {
this.noSleep = new NoSleep();