Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SmarterLocations #313

Merged
merged 7 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 54 additions & 36 deletions api/web/src/components/CloudTAK/Map.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,22 @@
class='position-absolute bottom-0 begin-0 text-white'
style='
z-index: 1;
width: 200px;
width: 250px;
height: 40px;
border-radius: 0px 6px 0px 0px;
background-color: rgba(0, 0, 0, 0.5);
'
>
<div class='d-flex align-items-center h-100'>
<div class='d-flex align-items-center' style='height: 40px'>
<Status
v-if='live_loc'
v-tooltip='"Using Live Location"'
class='mx-2 my-2'
status='success'
:dark='true'
/>
<div
v-else
v-tooltip='"Set Location"'
class='hover-button h-100 px-2 d-flex align-items-center cursor-pointer'
style='width: 40px;'
Expand Down Expand Up @@ -518,6 +526,7 @@

<script>
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';
Expand Down Expand Up @@ -678,14 +687,14 @@ 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,
dragging: false
},
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
Expand All @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -1021,17 +1040,15 @@ 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) {
connectionStore.sendCOT(profileStore.CoT());
}
}, 2000);

this.timerSelfUpdate = window.setInterval(() => {
this.getLocation(false);
}, 5000);

this.timer = window.setInterval(async () => {
if (!mapStore.map) return;
await this.updateCOT();
Expand All @@ -1043,6 +1060,7 @@ export default {
}
},
components: {
Status,
CoordInput,
WarnChannels,
SideMenu,
Expand Down
103 changes: 61 additions & 42 deletions api/web/src/components/CloudTAK/util/Coordinate.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class='col-12'>
<label class='subheader mx-2'>Coordinates</label>
<label class='subheader mx-2' v-text='label'></label>
<div class='mx-2'>
<CopyField
v-if='!edit'
Expand All @@ -13,46 +13,48 @@
@submit='$emit("submit")'
/>
</template>
<span
v-if='modes.includes("dd")'
v-tooltip='"Decimal Degrees"'
class='my-1 px-2'
:class='{
"bg-gray-500 rounded-bottom": mode === "dd",
"cursor-pointer": mode !== "dd",
}'
@click='mode = "dd"'
>DD</span>
<span
v-if='modes.includes("dms")'
v-tooltip='"Decimal Minutes Seconds"'
class='my-1 px-2'
:class='{
"bg-gray-500 rounded-bottom": mode === "dms",
"cursor-pointer": mode !== "dms",
}'
@click='mode = "dms"'
>DMS</span>
<span
v-if='modes.includes("mgrs")'
v-tooltip='"Military Grid Reference System"'
class='my-1 px-2'
:class='{
"bg-gray-500 rounded-bottom": mode === "mgrs",
"cursor-pointer": mode !== "mgrs",
}'
@click='mode = "mgrs"'
>MGRS</span>
<span
v-if='modes.includes("utm")'
v-tooltip='"Universal Transverse Mercator"'
class='my-1 px-2'
:class='{
"bg-gray-500 rounded-bottom": mode === "utm",
"cursor-pointer": mode !== "utm",
}'
@click='mode = "utm"'
>UTM</span>
<template v-if='modes.length'>
<span
v-if='modes.includes("dd")'
v-tooltip='"Decimal Degrees"'
class='my-1 px-2'
:class='{
"bg-gray-500 rounded-bottom": mode === "dd",
"cursor-pointer": mode !== "dd",
}'
@click='mode = "dd"'
>DD</span>
<span
v-if='modes.includes("dms")'
v-tooltip='"Decimal Minutes Seconds"'
class='my-1 px-2'
:class='{
"bg-gray-500 rounded-bottom": mode === "dms",
"cursor-pointer": mode !== "dms",
}'
@click='mode = "dms"'
>DMS</span>
<span
v-if='modes.includes("mgrs")'
v-tooltip='"Military Grid Reference System"'
class='my-1 px-2'
:class='{
"bg-gray-500 rounded-bottom": mode === "mgrs",
"cursor-pointer": mode !== "mgrs",
}'
@click='mode = "mgrs"'
>MGRS</span>
<span
v-if='modes.includes("utm")'
v-tooltip='"Universal Transverse Mercator"'
class='my-1 px-2'
:class='{
"bg-gray-500 rounded-bottom": mode === "utm",
"cursor-pointer": mode !== "utm",
}'
@click='mode = "utm"'
>UTM</span>
</template>
</div>
</div>
</template>
Expand All @@ -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() {
Expand All @@ -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]);
Expand Down
2 changes: 1 addition & 1 deletion api/web/src/components/CloudTAK/util/CopyField.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div
class='bg-gray-500 rounded-top py-2 px-2 position-relative'
class='bg-gray-500 rounded-top py-2 px-2 position-relative text-truncate'
>
<span v-text='text' />
<CopyButton
Expand Down
Loading