import WarnChannels from './util/WarnChannels.vue';
+import Status from '../util/Status.vue';
import CoordInput from './CoordInput.vue';
import { std, stdurl } from '/src/std.ts';
import CloudTAKFeatView from './FeatView.vue';
@@ -678,6 +687,7 @@ export default {
feat: null, // Show the Feat Viewer sidebar
locked: [], // Lock the map view to a given CoT - The last element is the currently locked value
// this is an array so that things like the radial menu can temporarily lock state but remember the previous lock value when they are closed
+ live_loc_denied: false, // User denied live location services
live_loc: false,
upload: {
shown: false,
@@ -685,7 +695,6 @@ export default {
},
timer: null, // Interval for pushing GeoJSON Map Updates (CoT)
timerSelf: null, // Interval for pushing your location to the server
- timerSelfUpdate: null, // Interval for updating actual GPS location
loading: {
// Any Loading related states
main: true
@@ -696,7 +705,6 @@ export default {
beforeUnmount: function() {
if (this.timer) window.clearInterval(this.timer);
if (this.timerSelf) window.clearInterval(this.timerSelf);
- if (this.timerSelfUpdate) window.clearInterval(this.timerSelfUpdate);
if (connectionStore.ws) connectionStore.ws.close();
if (mapStore.map) {
@@ -799,43 +807,54 @@ export default {
return mapStore.map.getZoom();
},
getLocation: function(flyTo = false) {
+ if (this.live_loc_denied && flyTo) throw new Error('Cannot navigate to your position as you denied location services');
+ else if (this.live_loc_denied) return;
+
if (flyTo && !("geolocation" in navigator)) {
throw new Error('GeoLocation is not available in this browser');
} else if (!("geolocation" in navigator)) {
+ console.error('geolocation object not found on navigator');
return;
}
- navigator.geolocation.getCurrentPosition(
- (position) => {
- if (flyTo) {
- mapStore.map.flyTo({
- center: [position.coords.longitude, position.coords.latitude],
- zoom: 14
- });
- } else if (position.coords.accuracy <= 500) {
- this.live_loc = {
- type: 'Feature',
- properties: {
- accuracy: position.coords.accuracy
- },
- geometry: {
- type: 'Point',
- coordinates: [
- position.coords.longitude,
- position.coords.latitude
- ],
- }
+ navigator.geolocation.getCurrentPosition((position) => {
+ if (flyTo) {
+ mapStore.map.flyTo({
+ center: [position.coords.longitude, position.coords.latitude],
+ zoom: 14
+ });
+ } else if (position.coords.accuracy <= 500) {
+ this.live_loc = {
+ type: 'Feature',
+ properties: {
+ accuracy: position.coords.accuracy
+ },
+ geometry: {
+ type: 'Point',
+ coordinates: [
+ position.coords.longitude,
+ position.coords.latitude
+ ],
}
-
- this.setYou(this.live_loc);
}
- }, (err) => {
- console.error(err);
- },{
- maximumAge: 300000,
- enableHighAccuracy: true
+
+ this.setYou(this.live_loc);
}
- );
+ }, (err) => {
+ if (err.message === 'User denied geolocation prompt') {
+ this.live_loc_denied = true;
+ } else if (
+ err.message !== 'Position unavailable'
+ && err.message !== 'Position acquisition timed out'
+ && err.message !== 'Timeout expired'
+ ) {
+ this.$emit('err', err);
+ }
+ },{
+ maximumAge: 0,
+ timeout: 1500,
+ enableHighAccuracy: true
+ });
},
startDraw: function(type) {
mapStore.draw.start();
@@ -1021,6 +1040,8 @@ export default {
});
this.timerSelf = window.setInterval(() => {
+ this.getLocation(false);
+
if (this.live_loc) {
connectionStore.sendCOT(profileStore.CoT(this.live_loc))
} else if (profileStore.profile.tak_loc) {
@@ -1028,10 +1049,6 @@ export default {
}
}, 2000);
- this.timerSelfUpdate = window.setInterval(() => {
- this.getLocation(false);
- }, 5000);
-
this.timer = window.setInterval(async () => {
if (!mapStore.map) return;
await this.updateCOT();
@@ -1043,6 +1060,7 @@ export default {
}
},
components: {
+ Status,
CoordInput,
WarnChannels,
SideMenu,
diff --git a/api/web/src/components/CloudTAK/util/Coordinate.vue b/api/web/src/components/CloudTAK/util/Coordinate.vue
index 5dfe08cf1..4d41d19e0 100644
--- a/api/web/src/components/CloudTAK/util/Coordinate.vue
+++ b/api/web/src/components/CloudTAK/util/Coordinate.vue
@@ -1,6 +1,6 @@
-
+
- DD
- DMS
- MGRS
- UTM
+
+ DD
+ DMS
+ MGRS
+ UTM
+
@@ -70,10 +72,18 @@ export default {
CopyField,
},
props: {
+ label: {
+ type: String,
+ default: 'Coordinates'
+ },
edit: {
type: Boolean,
default: false
},
+ truncate: {
+ type: Number,
+ description: 'Truncate DD coordinates to a given precision'
+ },
modes: {
type: Array,
default: function() {
@@ -98,7 +108,16 @@ export default {
},
computed: {
inMode: function() {
- if (this.mode === 'dd') return `${this.modelValue[1]}, ${this.modelValue[0]}`;
+ if (this.mode === 'dd') {
+ if (this.truncate) {
+ return [
+ Math.trunc(this.modelValue[1] * Math.pow(10, this.truncate)) / Math.pow(10, this.truncate),
+ Math.trunc(this.modelValue[0] * Math.pow(10, this.truncate)) / Math.pow(10, this.truncate)
+ ].join(', ');
+ } else {
+ return `${this.modelValue[1]}, ${this.modelValue[0]}`;
+ }
+ }
else if (this.mode === 'dms') return `${this.asDMS(this.modelValue[1])}, ${this.asDMS(this.modelValue[0])}`;
else if (this.mode === 'mgrs') return this.asMGRS();
else if (this.mode === 'utm') return this.asUTM(this.modelValue[1], this.modelValue[0]);
diff --git a/api/web/src/components/CloudTAK/util/CopyField.vue b/api/web/src/components/CloudTAK/util/CopyField.vue
index 5bd54739e..e234cabf7 100644
--- a/api/web/src/components/CloudTAK/util/CopyField.vue
+++ b/api/web/src/components/CloudTAK/util/CopyField.vue
@@ -1,6 +1,6 @@