Compare commits

...

121 Commits

Author SHA1 Message Date
Jamie Vigliotta
eb97e94cd6 fixed img url for tests 2021-02-19 16:32:33 -08:00
Jamie Vigliotta
e7b8c42f02 making v-for key truly unique 2021-02-19 11:14:00 -08:00
Andrew Henry
3810b6c441 Merge branch 'master' into imagery-enhancements 2021-02-19 08:30:07 -08:00
Jamie V
2c62b4c1bc Merge branch 'master' into imagery-enhancements 2021-02-18 11:09:32 -08:00
Jamie Vigliotta
ca47fb6f2d Merge branch 'imagery-enhancements' of https://github.com/nasa/openmct into imagery-enhancements
Merg'n
2021-02-18 10:51:35 -08:00
Jamie Vigliotta
5d4d87cd89 copying functions properly 2021-02-18 10:51:21 -08:00
Jamie V
f32602343d Merge branch 'master' into imagery-enhancements 2021-02-18 08:48:20 -08:00
Jamie Vigliotta
bf82abd464 cleaning up 2021-02-17 21:41:59 -08:00
Jamie Vigliotta
ab31581ea4 wronge word 2021-02-17 21:39:50 -08:00
Jamie Vigliotta
35bad9cb82 removing unused code 2021-02-17 21:38:57 -08:00
Jamie Vigliotta
03a104c9f5 moved related telemetry bulk out to a class, updates based on PR comments 2021-02-17 21:35:18 -08:00
Jamie V
99ace5ec9b Merge branch 'master' into imagery-enhancements 2021-02-16 14:42:12 -08:00
Andrew Henry
93785544f1 Merge branch 'master' into imagery-enhancements 2021-02-12 17:20:26 -08:00
Jamie V
ed0095fc00 Merge branch 'master' into imagery-enhancements 2021-02-10 11:13:37 -08:00
Jamie Vigliotta
63cf6e8156 removing comment 2021-02-08 13:43:53 -08:00
Jamie Vigliotta
e8600d23e1 removing dev code 2021-02-08 12:44:48 -08:00
Jamie Vigliotta
36e720ad85 removing dev code 2021-02-08 12:42:29 -08:00
Jamie Vigliotta
46e926aa08 Merge branch 'master' into imagery-enhancements
Merge'n master
2021-02-08 09:43:53 -08:00
Jamie Vigliotta
429a628c92 polishing freshness logic, debuggin, WIP 2021-02-08 09:43:05 -08:00
Jamie Vigliotta
03e1229576 debuggin 2021-02-05 14:51:37 -08:00
Jamie Vigliotta
05c8a8a2f0 debuggin 2021-02-05 14:38:38 -08:00
Jamie Vigliotta
7a7ec7c9b7 debuggin 2021-02-05 14:26:27 -08:00
Jamie Vigliotta
b5fcda3107 testing: calling compare function directly instead of assigned to variable 2021-02-05 12:28:42 -08:00
Jamie Vigliotta
ab4e770b79 removed frame id stuff, will be handled in config comparison functions 2021-02-05 09:10:53 -08:00
Jamie Vigliotta
3f140de03a checking if datum exists before looking for keys on it 2021-02-04 18:52:09 -08:00
Jamie Vigliotta
9ee6cca07d WIP commenting out frame id stuff 2021-02-04 18:36:11 -08:00
Jamie Vigliotta
54182e400a timekey not working, fallback to timestamp 2021-02-04 18:02:49 -08:00
Jamie Vigliotta
863533910e removing frame id stuff it will be handled in comparison functions 2021-02-04 17:44:01 -08:00
Jamie Vigliotta
edbdf432d1 changed v-for key to timestamp of image, URL was throwing dupe key errors... could just be from how example imagery is setup, but this should be safe 2021-02-04 15:41:14 -08:00
Jamie Vigliotta
35256b6e96 moved comparison function back to config 2021-02-04 15:09:31 -08:00
Jamie Vigliotta
375bbd244e updated variable name 2021-02-04 14:59:01 -08:00
Jamie Vigliotta
8090e27b7b updated keys 2021-02-04 14:57:32 -08:00
Jamie Vigliotta
275410f99c finessing some code 2021-02-04 14:27:28 -08:00
Jamie Vigliotta
31ab08c9d3 merging compass-rose into imagery-enhancements branch 2021-02-04 13:43:30 -08:00
Jamie Vigliotta
082a89440e mas testing 2021-02-04 11:16:24 -08:00
Jamie Vigliotta
c729732541 removing some console logs, that was rediculous... 2021-02-04 10:32:26 -08:00
Jamie Vigliotta
8d3737912b testing 2021-02-04 09:55:58 -08:00
Jamie Vigliotta
d6a71adb7f Merge branch 'imagery-enhancements' into imagery-freshness
Merge'n main imagery branch
2021-02-04 09:52:06 -08:00
Jamie Vigliotta
8397b13c57 Merge branch 'master' into imagery-enhancements
Merge'n master
2021-02-04 09:51:31 -08:00
Jamie Vigliotta
6a4ceb5219 testing 2021-02-04 09:36:34 -08:00
Jamie Vigliotta
c25b196b8f more debuggin 2021-02-03 14:23:51 -08:00
Jamie Vigliotta
cd5cc4c76c debuggin 2021-02-03 13:27:50 -08:00
Jamie Vigliotta
f8b818e78b Merge branch 'imagery-enhancements' into imagery-freshness
Merge'n main imagery branch in
2021-02-03 11:17:50 -08:00
Jamie Vigliotta
6cea1a77e5 setting a promise to be resolved when related telemetry is setup 2021-02-03 11:17:32 -08:00
Jamie Vigliotta
88ff09857b WIP: debuggin 2021-02-02 15:23:25 -08:00
Jamie Vigliotta
b409d3cb1e Merge branch 'imagery-enhancements' into imagery-freshness
Merge'n main imagery branch
2021-02-02 11:16:20 -08:00
Jamie Vigliotta
a64e3e5ca0 caopying image metadata since for dev we add information and it was persisting 2021-02-02 11:15:44 -08:00
Jamie Vigliotta
d6ba2f8b4c adding related directly to imageHistory array item 2021-02-02 11:06:52 -08:00
Jamie Vigliotta
4f1642a8d6 Merge branch 'imagery-enhancements' into imagery-freshness
Merge'n main imagery branch in
2021-02-02 11:01:37 -08:00
Jamie Vigliotta
9b73b45ba9 WIP: merging in some main branch stuff that was in freshness branch 2021-02-02 10:47:09 -08:00
charlesh88
98a048062f Added minor ordinal ticks to rose
- Added NE, SE, SW and NW ticks to compass rose;
2021-02-01 22:29:51 -08:00
David Tsay
9b114c49df cleanup 2021-01-29 14:49:44 -08:00
David Tsay
2c0c998e29 cleanup 2021-01-29 14:16:51 -08:00
David Tsay
a001e07600 Merge branch 'imagery-enhancements' into compass-rose 2021-01-29 14:11:02 -08:00
Jamie Vigliotta
157564487d equal func on metadata 2021-01-29 12:42:59 -08:00
Jamie Vigliotta
fcbd8c682a include rover pos for camera freshness check as well as add frame id stuff 2021-01-29 12:26:46 -08:00
David Tsay
4b40233bf3 remove unnused code 2021-01-29 11:34:28 -08:00
Jamie Vigliotta
fa2197f9c1 Merge branch 'imagery-enhancements' into imagery-freshness
Merge'n main imager branch in
2021-01-29 10:33:24 -08:00
Jamie Vigliotta
f3f833a337 WIP adding debug code for viper env testing 2021-01-29 10:23:17 -08:00
David Tsay
e6e8b8e048 Merge branch 'imagery-enhancements' into compass-rose 2021-01-28 11:28:25 -08:00
David Tsay
6a2c079336 fix click on compass rose
fix hud pointer
2021-01-28 11:25:30 -08:00
Jamie Vigliotta
0d23fe3d14 Merge branch 'imagery-enhancements' into imagery-freshness
Merge'n in main imagery-enhancements branch
2021-01-28 11:02:59 -08:00
Jamie Vigliotta
1d645a8472 moving equal comparison back out of metadata, and adding in tolerance instead 2021-01-28 11:00:41 -08:00
David Tsay
334aeb42ae do not unskew lettering in hud 2021-01-28 10:30:07 -08:00
David Tsay
5900bb0d98 add rover roll skew to hud 2021-01-27 21:36:28 -08:00
David Tsay
a2c350b105 include camera pan in calculations 2021-01-27 20:32:34 -08:00
David Tsay
174f212328 make compass hud reactive 2021-01-27 18:40:06 -08:00
Jamie Vigliotta
a28ec45f71 liniting 2021-01-26 12:17:48 -08:00
Jamie Vigliotta
fcc6bb9873 Merge branch 'master' into imagery-enhancements
Merg'n master
2021-01-26 11:24:18 -08:00
David Tsay
45578b113f cleanup from refactor compass out of imagery-view component 2021-01-25 23:15:26 -08:00
David Tsay
5ef14b0975 move compass logic to component 2021-01-25 23:00:58 -08:00
David Tsay
2be429a04f compass rose and hud should be part of compass component 2021-01-25 22:25:20 -08:00
Jamie Vigliotta
c4ce405b1e couple tweaks on freshness indicators 2021-01-25 17:28:50 -08:00
Jamie Vigliotta
b95f844a4e merged in imagery-enhancement changes 2021-01-25 13:55:08 -08:00
David Tsay
3804fe1a1e merge imagery-enhancements 2021-01-25 13:53:50 -08:00
David Tsay
7576673e77 Merge branch 'imagery-enhancements' into compass-rose 2021-01-25 13:51:31 -08:00
Jamie Vigliotta
63e04caab6 remove old cod 2021-01-25 13:41:54 -08:00
Jamie Vigliotta
956cfbd01f removed space, linting 2021-01-25 13:40:11 -08:00
Jamie Vigliotta
6c77be32c7 updates from imagery-freshness branch that were supposed to be in this branch 2021-01-25 13:35:55 -08:00
Jamie Vigliotta
af4c7c9ca0 WIP: update test data for restructured metadata format and code that uses it 2021-01-25 12:32:39 -08:00
Jamie Vigliotta
1697362994 WIP: updated to LAD reqs 2021-01-25 11:29:48 -08:00
Jamie Vigliotta
e69911385f WIP: removed tracking for historical, LAD will be used instead, added tracking flag for subscriptions 2021-01-25 10:58:28 -08:00
Jamie Vigliotta
6478267cbe added sun keys to latest data tracking 2021-01-25 10:29:20 -08:00
Jamie Vigliotta
22d53c1ccd WIP: removing rerequest of telemetry since we will do a LAD each time, not store historical 2021-01-25 10:28:28 -08:00
Jamie Vigliotta
633a95dd27 WIP: removed sameId checks since realtime and historical will ALWAYS be different 2021-01-25 10:25:17 -08:00
David Tsay
f732167e02 compass rose and hud listening to live metadata 2021-01-25 08:51:52 -08:00
Jamie Vigliotta
50ff26ad5d Merge branch 'imagery-freshness' of https://github.com/nasa/openmct into imagery-freshness
Merg'n in charles updates!
2021-01-22 15:17:03 -08:00
charlesh88
f056e8e57b Imagery positional and camera freshness
- Refined content and styling;
- Improved color styling and flashing animation;
2021-01-22 14:21:08 -08:00
David Tsay
1d56fd98dc Merge branch 'imagery-enhancements' into compass-rose 2021-01-22 10:10:28 -08:00
Jamie Vigliotta
320217f8c4 Merge branch 'imagery-enhancements' into imagery-freshness
Merg'n latest updates from main branch (on telemetry data)
2021-01-21 15:55:38 -08:00
Jamie Vigliotta
b43fef6e21 added a check for on telemetry related data, handling accordingly by not requesting data and just returning it if it exists on the datum 2021-01-21 15:55:16 -08:00
Jamie Vigliotta
d04c29345b removed splice of image backinto image history, looks like we didnt need it since the changes were made on an object which kept its reference in the array 2021-01-21 13:18:18 -08:00
Jamie Vigliotta
49afec5cdd setup freshness computed variables for rover position and camera position 2021-01-21 12:50:33 -08:00
David Tsay
24b96cdb47 WIP get image container size to resize HUD element 2021-01-21 11:58:28 -08:00
David Tsay
14ce4a1aa0 Merge branch 'imagery-enhancements' into compass-rose 2021-01-21 09:46:26 -08:00
Jamie Vigliotta
43a8901c34 Merge branch 'imagery-enhancements' into imagery-freshness
Keeping up to date with main branch changes
2021-01-21 09:43:03 -08:00
Jamie Vigliotta
28d97be60e adding keys to data object 2021-01-21 09:42:15 -08:00
Jamie Vigliotta
4bb2b35124 setting keys to data object 2021-01-21 09:40:58 -08:00
David Tsay
1f6e91c6b5 add true sun heading from metadata 2021-01-21 09:34:26 -08:00
David Tsay
0b078497f1 Merge branch 'imagery-enhancements' into compass-rose 2021-01-21 09:33:50 -08:00
David Tsay
060a1b17db add sun heading to related telemetry 2021-01-21 09:33:29 -08:00
Jamie Vigliotta
db50b8b732 Merge branch 'imagery-enhancements' into imagery-freshness
Merg'n in main imagery branch updates
2021-01-21 09:21:08 -08:00
Jamie Vigliotta
62de05808e WIP 2021-01-21 09:20:30 -08:00
David Tsay
417f81b7fd connect compass rose to image metadata
add compass HUD
2021-01-20 20:43:00 -08:00
David Tsay
f219394abd Merge branch 'imagery-enhancements' into compass-rose 2021-01-20 16:48:35 -08:00
David Tsay
4e5c74ecef add metadata to this.focusedImage 2021-01-20 16:47:53 -08:00
David Tsay
218530e436 telemetry changes 2021-01-20 15:58:06 -08:00
David Tsay
0890499a2b Merge branch 'imagery-enhancements' into compass-rose 2021-01-20 15:00:35 -08:00
Jamie Vigliotta
d9dad09dfd lazy related telemetry data grab, added focused image related data key 2021-01-20 14:34:55 -08:00
David Tsay
9af5df0f20 Merge branch 'imagery-enhancements' into compass-rose 2021-01-20 10:44:47 -08:00
David Tsay
1580a61092 Merge branch 'master' into imagery-enhancements 2021-01-20 10:43:43 -08:00
Jamie Vigliotta
c236444a05 added options for request 2021-01-19 19:51:55 -08:00
Jamie Vigliotta
39c1eb1d5b added revised functionality for getting related telemetry data with examples and local testing settings as well 2021-01-19 19:49:22 -08:00
David Tsay
95caab944d Merge branch 'imagery-enhancements' into compass-rose 2021-01-15 08:39:43 -08:00
David Tsay
ac89e51d1b Merge branch 'master' into imagery-enhancements 2021-01-15 08:39:23 -08:00
David Tsay
85d9ed8287 unhardcode camera field of view
add toggle lock feature
2021-01-14 20:24:12 -08:00
David Tsay
aedc24a2da unhardcode headings and cardinal points 2021-01-14 16:14:38 -08:00
David Tsay
823eda4465 linting 2021-01-14 13:08:33 -08:00
David Tsay
7eaa1d3e2b add markup for compass rose component 2021-01-14 13:06:08 -08:00
Jamie Vigliotta
4633436cbd added get imageMetadataValue method for getting necessary values for new image enhancements, has temporary local testing code as well for dev 2021-01-13 15:16:03 -08:00
David Tsay
b68a7e27c9 add missing copyrights 2021-01-12 16:19:51 -08:00
12 changed files with 1309 additions and 26 deletions

View File

@@ -1,3 +1,25 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import ImageryViewLayout from './components/ImageryViewLayout.vue';
import Vue from 'vue';

View File

@@ -0,0 +1,127 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div
class="c-compass"
:style="compassDimensionsStyle"
>
<CompassHUD
v-if="shouldDisplayCompassHUD"
:heading="heading"
:roll="roll"
:sun-heading="sunHeading"
:camera-field-of-view="cameraFieldOfView"
:camera-pan="cameraPan"
/>
<CompassRose
v-if="shouldDisplayCompassRose"
:heading="heading"
:sun-heading="sunHeading"
:camera-field-of-view="cameraFieldOfView"
:camera-pan="cameraPan"
/>
</div>
</template>
<script>
import CompassHUD from './CompassHUD.vue';
import CompassRose from './CompassRose.vue';
const CAM_FIELD_OF_VIEW = 70;
export default {
components: {
CompassHUD,
CompassRose
},
props: {
containerWidth: {
type: Number,
required: true
},
containerHeight: {
type: Number,
required: true
},
naturalAspectRatio: {
type: Number,
required: true
},
image: {
type: Object,
required: true
}
},
computed: {
shouldDisplayCompassRose() {
return this.heading !== undefined;
},
shouldDisplayCompassHUD() {
return this.heading !== undefined;
},
// degrees from north heading
heading() {
return this.image.heading;
},
roll() {
return this.image.roll;
},
pitch() {
return this.image.pitch;
},
// degrees from north heading
sunHeading() {
return this.image.sunOrientation;
},
// degrees from spacecraft heading
cameraPan() {
return this.image.cameraPan;
},
cameraTilt() {
return this.image.cameraTilt;
},
cameraFieldOfView() {
return CAM_FIELD_OF_VIEW;
},
compassDimensionsStyle() {
const containerAspectRatio = this.containerWidth / this.containerHeight;
let width;
let height;
if (containerAspectRatio < this.naturalAspectRatio) {
width = '100%';
height = `${ this.containerWidth / this.naturalAspectRatio }px`;
} else {
width = `${ this.containerHeight * this.naturalAspectRatio }px`;
height = '100%';
}
return {
width: width,
height: height
};
}
}
};
</script>

View File

@@ -0,0 +1,171 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div
class="c-compass__hud c-hud"
:style="skewCompassHUDStyle"
>
<div
v-for="point in visibleCompassPoints"
:key="point.direction"
:class="point.class"
:style="point.style"
>
{{ point.direction }}
</div>
<div
v-if="isSunInRange"
ref="sun"
class="c-hud__sun"
:style="sunPositionStyle"
></div>
<div class="c-hud__range"></div>
</div>
</template>
<script>
import {
normalizeDegrees,
inRange,
percentOfRange
} from './utils';
const COMPASS_POINTS = [
{
direction: 'N',
class: 'c-hud__dir',
degrees: 0
},
{
direction: 'NE',
class: 'c-hud__dir--sub',
degrees: 45
},
{
direction: 'E',
class: 'c-hud__dir',
degrees: 90
},
{
direction: 'SE',
class: 'c-hud__dir--sub',
degrees: 135
},
{
direction: 'S',
class: 'c-hud__dir',
degrees: 180
},
{
direction: 'SW',
class: 'c-hud__dir--sub',
degrees: 225
},
{
direction: 'W',
class: 'c-hud__dir',
degrees: 270
},
{
direction: 'NW',
class: 'c-hud__dir--sub',
degrees: 315
}
];
export default {
props: {
heading: {
type: Number,
required: true
},
roll: {
type: Number,
default: undefined
},
sunHeading: {
type: Number,
default: undefined
},
cameraFieldOfView: {
type: Number,
default: undefined
},
cameraPan: {
type: Number,
default: undefined
}
},
computed: {
skewCompassHUDStyle() {
if (this.roll === undefined || this.roll === 0) {
return;
}
const origin = this.roll > 0 ? 'left bottom' : 'right top';
return {
'transform-origin': origin,
transform: `skew(0, ${ this.roll }deg`
};
},
visibleCompassPoints() {
return COMPASS_POINTS
.filter(point => inRange(point.degrees, this.visibleRange))
.map(point => {
const percentage = percentOfRange(point.degrees, this.visibleRange);
point.style = Object.assign(
{ left: `${ percentage * 100 }%` }
);
return point;
});
},
isSunInRange() {
return inRange(this.normalizedSunHeading, this.visibleRange);
},
sunPositionStyle() {
const percentage = percentOfRange(this.normalizedSunHeading, this.visibleRange);
return {
left: `${ percentage * 100 }%`
};
},
normalizedSunHeading() {
return normalizeDegrees(this.sunHeading);
},
normalizedHeading() {
return normalizeDegrees(this.heading);
},
visibleRange() {
const min = normalizeDegrees(this.normalizedHeading + this.cameraPan - this.cameraFieldOfView / 2);
const max = normalizeDegrees(this.normalizedHeading + this.cameraPan + this.cameraFieldOfView / 2);
return [
min,
max
];
}
}
};
</script>

View File

@@ -0,0 +1,262 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div
class="c-direction-rose"
@click="toggleBezelLock"
>
<div
class="c-nsew"
:style="rotateFrameStyle"
>
<svg
class="c-nsew__minor-ticks"
viewBox="0 0 100 100"
>
<rect
class="c-nsew__tick c-tick-ne"
x="49"
y="0"
width="2"
height="5"
/>
<rect
class="c-nsew__tick c-tick-se"
x="95"
y="49"
width="5"
height="2"
/>
<rect
class="c-nsew__tick c-tick-sw"
x="49"
y="95"
width="2"
height="5"
/>
<rect
class="c-nsew__tick c-tick-nw"
x="0"
y="49"
width="5"
height="2"
/>
</svg>
<svg
class="c-nsew__ticks"
viewBox="0 0 100 100"
>
<polygon
class="c-nsew__tick c-tick-n"
points="50,0 57,5 43,5"
/>
<rect
class="c-nsew__tick c-tick-e"
x="95"
y="49"
width="5"
height="2"
/>
<rect
class="c-nsew__tick c-tick-w"
x="0"
y="49"
width="5"
height="2"
/>
<rect
class="c-nsew__tick c-tick-s"
x="49"
y="95"
width="2"
height="5"
/>
<text
class="c-nsew__label c-label-n"
text-anchor="middle"
:transform="northTextTransform"
>N</text>
<text
class="c-nsew__label c-label-e"
text-anchor="middle"
:transform="eastTextTransform"
>E</text>
<text
class="c-nsew__label c-label-w"
text-anchor="middle"
:transform="southTextTransform"
>W</text>
<text
class="c-nsew__label c-label-s"
text-anchor="middle"
:transform="westTextTransform"
>S</text>
</svg>
</div>
<div
class="c-spacecraft-body"
:style="headingStyle"
>
</div>
<div
class="c-sun"
:style="sunHeadingStyle"
></div>
<div
v-if="showCameraFOV"
class="c-cam-field"
:style="cameraFOVHeadingStyle"
>
<div class="cam-field-half cam-field-half-l">
<div
class="cam-field-area"
:style="cameraFOVStyleLeftHalf"
></div>
</div>
<div class="cam-field-half cam-field-half-r">
<div
class="cam-field-area"
:style="cameraFOVStyleRightHalf"
></div>
</div>
</div>
</div>
</template>
<script>
import { normalizeDegrees } from './utils';
export default {
props: {
heading: {
type: Number,
required: true
},
sunHeading: {
type: Number,
default: undefined
},
cameraFieldOfView: {
type: Number,
default: undefined
},
cameraPan: {
type: Number,
default: undefined
}
},
data() {
return {
lockBezel: true
};
},
computed: {
compassHeading() {
return this.lockBezel ? normalizeDegrees(this.heading) : 0;
},
north() {
return normalizeDegrees(this.compassHeading - this.heading);
},
rotateFrameStyle() {
return { transform: `rotate(${ this.north }deg)` };
},
northTextTransform() {
return this.cardinalPointsTextTransform.north;
},
eastTextTransform() {
return this.cardinalPointsTextTransform.east;
},
southTextTransform() {
return this.cardinalPointsTextTransform.south;
},
westTextTransform() {
return this.cardinalPointsTextTransform.west;
},
cardinalPointsTextTransform() {
/**
* cardinal points text must be rotated
* in the opposite direction that north is rotated
* to keep text vertically oriented
*/
const rotation = `rotate(${ -this.north })`;
return {
north: `translate(50,15) ${ rotation }`,
east: `translate(87,50) ${ rotation }`,
south: `translate(13,50) ${ rotation }`,
west: `translate(50,87) ${ rotation }`
};
},
headingStyle() {
return {
transform: `translateX(-50%) rotate(${ this.compassHeading }deg)`
};
},
cameraFOVHeading() {
return this.compassHeading + this.cameraPan;
},
cameraFOVHeadingStyle() {
return {
transform: `rotate(${ this.cameraFOVHeading }deg)`
};
},
sunHeadingStyle() {
const rotation = normalizeDegrees(this.north + this.sunHeading);
return {
transform: `rotate(${ rotation }deg)`
};
},
showCameraFOV() {
return this.cameraPan !== undefined && this.cameraFieldOfView > 0;
},
// left half of camera field of view
// rotated counter-clockwise from camera field of view heading
cameraFOVStyleLeftHalf() {
return {
transform: `translateX(50%) rotate(${ -this.cameraFieldOfView / 2 }deg)`
};
},
// right half of camera field of view
// rotated clockwise from camera field of view heading
cameraFOVStyleRightHalf() {
return {
transform: `translateX(-50%) rotate(${ this.cameraFieldOfView / 2 }deg)`
};
}
},
methods: {
toggleBezelLock() {
this.lockBezel = !this.lockBezel;
}
}
};
</script>

View File

@@ -0,0 +1,216 @@
/***************************** THEME/UI CONSTANTS AND MIXINS */
$interfaceKeyColor: #00B9C5;
$elemBg: rgba(black, 0.7);
@mixin sun($position: 'circle closest-side') {
$color: #ff9900;
$gradEdgePerc: 60%;
background: radial-gradient(#{$position}, $color, $color $gradEdgePerc, rgba($color, 0.4) $gradEdgePerc + 5%, transparent);
}
.c-compass {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 1;
@include userSelectNone;
}
/***************************** COMPASS HUD */
.c-hud {
// To be placed within a imagery view, in the bounding box of the image
$m: 1px;
$padTB: 2px;
$padLR: $padTB;
background: $elemBg;
border-radius: 3px;
color: $interfaceKeyColor;
font-size: 0.8em;
position: absolute;
top: $m; right: $m; left: $m;
height: 18px;
svg, div {
position: absolute;
}
&__display {
height: 30px;
pointer-events: all;
position: absolute;
top: 0;
right: 0;
left: 0;
}
&__range {
border: 1px solid $interfaceKeyColor;
border-top-color: transparent;
position: absolute;
top: 50%; right: $padLR; bottom: $padTB; left: $padLR;
}
[class*="__dir"] {
// NSEW
display: inline-block;
font-weight: bold;
text-shadow: black 0 0 3px;
top: 50%;
transform: translate(-50%,-50%);
z-index: 2;
}
[class*="__dir--sub"] {
font-weight: normal;
opacity: 0.5;
}
&__sun {
$s: 10px;
@include sun('circle farthest-side at bottom');
bottom: $padTB + 2px;
height: $s; width: $s*2;
opacity: 0.8;
transform: translateX(-50%);
z-index: 1;
}
}
/***************************** COMPASS DIRECTIONS */
.c-nsew {
$color: $interfaceKeyColor;
$inset: 7%;
$tickHeightPerc: 15%;
text-shadow: black 0 0 10px;
top: $inset; right: $inset; bottom: $inset; left: $inset;
z-index: 3;
&__tick,
&__label {
fill: $color;
}
&__minor-ticks {
opacity: 0.5;
transform-origin: center;
transform: rotate(45deg);
}
&__label {
dominant-baseline: central;
font-size: 0.8em;
font-weight: bold;
}
.c-label-n {
font-size: 1.1em;
}
}
/***************************** CAMERA FIELD ANGLE */
.c-cam-field {
$color: white;
opacity: 0.2;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
.cam-field-half {
top: 0;
right: 0;
bottom: 0;
left: 0;
.cam-field-area {
background: $color;
top: -30%;
right: 0;
bottom: -30%;
left: 0;
}
// clip-paths overlap a bit to avoid a gap between halves
&-l {
clip-path: polygon(0 0, 50.5% 0, 50.5% 100%, 0 100%);
.cam-field-area {
transform-origin: left center;
}
}
&-r {
clip-path: polygon(49.5% 0, 100% 0, 100% 100%, 49.5% 100%);
.cam-field-area {
transform-origin: right center;
}
}
}
}
/***************************** SPACECRAFT BODY */
.c-spacecraft-body {
$color: $interfaceKeyColor;
$s: 30%;
background: $color;
border-radius: 3px;
height: $s; width: $s;
left: 50%; top: 50%;
opacity: 0.4;
transform-origin: center top;
&:before {
// Direction arrow
$color: rgba(black, 0.5);
$arwPointerY: 60%;
$arwBodyOffset: 25%;
background: $color;
content: '';
display: block;
position: absolute;
top: 10%; right: 20%; bottom: 50%; left: 20%;
clip-path: polygon(50% 0, 100% $arwPointerY, 100%-$arwBodyOffset $arwPointerY, 100%-$arwBodyOffset 100%, $arwBodyOffset 100%, $arwBodyOffset $arwPointerY, 0 $arwPointerY);
}
}
/***************************** DIRECTION ROSE */
.c-direction-rose {
$d: 100px;
$c2: rgba(white, 0.1);
background: $elemBg;
background-image: radial-gradient(circle closest-side, transparent, transparent 80%, $c2);
width: $d;
height: $d;
transform-origin: 0 0;
position: absolute;
bottom: 10px; left: 10px;
clip-path: circle(50% at 50% 50%);
border-radius: 100%;
svg, div {
position: absolute;
}
// Sun
.c-sun {
top: 0;
right: 0;
bottom: 0;
left: 0;
&:before {
$s: 35%;
@include sun();
content: '';
display: block;
position: absolute;
opacity: 0.7;
top: 0; left: 50%;
height:$s; width: $s;
transform: translate(-50%, -60%);
}
}
}

View File

@@ -0,0 +1,44 @@
export function normalizeDegrees(degrees) {
const base = degrees % 360;
return base >= 0 ? base : 360 + base;
}
export function inRange(degrees, [min, max]) {
return min > max
? (degrees >= min && degrees < 360) || (degrees <= max && degrees >= 0)
: degrees >= min && degrees <= max;
}
export function percentOfRange(degrees, [min, max]) {
let distance = degrees;
let minRange = min;
let maxRange = max;
if (min > max) {
if (distance < max) {
distance += 360;
}
maxRange += 360;
}
return (distance - minRange) / (maxRange - minRange);
}
export function normalizeSemiCircleDegrees(rawDegrees) {
// in case tony hawk is providing us degrees
let degrees = rawDegrees % 360;
// westward degrees are between 0 and -180 exclusively
if (degrees > 180) {
degrees = degrees - 360;
}
// eastward degrees are between 0 and 180 inclusively
if (degrees <= -180) {
degrees = 360 - degrees;
}
return degrees;
}

View File

@@ -1,3 +1,25 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div
tabindex="0"
@@ -36,14 +58,23 @@
<div class="c-imagery__main-image__bg"
:class="{'paused unnsynced': isPaused,'stale':false }"
>
<div class="c-imagery__main-image__image js-imageryView-image"
:style="{
'background-image': imageUrl ? `url(${imageUrl})` : 'none',
'filter': `brightness(${filters.brightness}%) contrast(${filters.contrast}%)`
}"
:data-openmct-image-timestamp="time"
:data-openmct-object-keystring="keyString"
></div>
<img
ref="focusedImage"
class="c-imagery__main-image__image js-imageryView-image"
:src="imageUrl"
:style="{
'filter': `brightness(${filters.brightness}%) contrast(${filters.contrast}%)`
}"
:data-openmct-image-timestamp="time"
:data-openmct-object-keystring="keyString"
>
<Compass
v-if="shouldDisplayCompass"
:container-width="imageContainerWidth"
:container-height="imageContainerHeight"
:natural-aspect-ratio="focusedImageNaturalAspectRatio"
:image="focusedImage"
/>
</div>
<div class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-buttons">
<button class="c-nav c-nav--prev"
@@ -61,11 +92,25 @@
<div class="c-imagery__control-bar">
<div class="c-imagery__time">
<div class="c-imagery__timestamp u-style-receiver js-style-receiver">{{ time }}</div>
<!-- image fresh -->
<div
v-if="canTrackDuration"
:class="{'c-imagery--new': isImageNew && !refreshCSS}"
class="c-imagery__age icon-timer"
>{{ formattedDuration }}</div>
<!-- spacecraft position fresh -->
<div
v-if="relatedTelemetry.hasRelatedTelemetry && isSpacecraftPositionFresh"
class="c-imagery__age icon-check c-imagery--new"
>POS</div>
<!-- camera position fresh -->
<div
v-if="relatedTelemetry.hasRelatedTelemetry && isCameraPositionFresh"
class="c-imagery__age icon-check c-imagery--new"
>CAM</div>
</div>
<div class="h-local-controls">
<button
@@ -76,13 +121,14 @@
</div>
</div>
</div>
<div ref="thumbsWrapper"
class="c-imagery__thumbs-wrapper"
:class="{'is-paused': isPaused}"
@scroll="handleScroll"
<div
ref="thumbsWrapper"
class="c-imagery__thumbs-wrapper"
:class="{'is-paused': isPaused}"
@scroll="handleScroll"
>
<div v-for="(datum, index) in imageHistory"
:key="datum.url"
:key="datum.url + datum[timeKey]"
class="c-imagery__thumb c-thumb"
:class="{ selected: focusedImageIndex === index && isPaused }"
@click="setFocusedImage(index, thumbnailClick)"
@@ -97,7 +143,10 @@
</template>
<script>
import _ from 'lodash';
import moment from 'moment';
import Compass from './Compass/Compass.vue';
import RelatedTelemetry from './RelatedTelemetry/RelatedTelemetry';
const DEFAULT_DURATION_FORMATTER = 'duration';
const REFRESH_CSS_MS = 500;
@@ -116,6 +165,9 @@ const ARROW_RIGHT = 39;
const ARROW_LEFT = 37;
export default {
components: {
Compass
},
inject: ['openmct', 'domainObject'],
data() {
let timeSystem = this.openmct.time.timeSystem();
@@ -137,7 +189,14 @@ export default {
refreshCSS: false,
keyString: undefined,
focusedImageIndex: undefined,
numericDuration: undefined
focusedImageRelatedTelemetry: {},
numericDuration: undefined,
metadataEndpoints: {},
relatedTelemetry: {},
latestRelatedTelemetry: {},
focusedImageNaturalAspectRatio: undefined,
imageContainerWidth: undefined,
imageContainerHeight: undefined
};
},
computed: {
@@ -195,15 +254,69 @@ export default {
}
return result;
},
shouldDisplayCompass() {
return this.focusedImage !== undefined
&& this.focusedImageNaturalAspectRatio !== undefined
&& this.imageContainerWidth !== undefined
&& this.imageContainerHeight !== undefined;
},
isSpacecraftPositionFresh() {
let isFresh = undefined;
let latest = this.latestRelatedTelemetry;
let focused = this.focusedImageRelatedTelemetry;
if (this.relatedTelemetry.hasRelatedTelemetry) {
isFresh = true;
for (let key of this.spacecraftKeys) {
if (this.relatedTelemetry[key] && latest[key] && focused[key]) {
if (!this.relatedTelemetry[key].comparisonFunction(latest[key], focused[key])) {
isFresh = false;
}
} else {
isFresh = false;
}
}
}
return isFresh;
},
isCameraPositionFresh() {
let isFresh = undefined;
let latest = this.latestRelatedTelemetry;
let focused = this.focusedImageRelatedTelemetry;
if (this.relatedTelemetry.hasRelatedTelemetry) {
isFresh = true;
// camera freshness relies on spacecraft position freshness
if (this.isSpacecraftPositionFresh) {
for (let key of this.cameraKeys) {
if (this.relatedTelemetry[key] && latest[key] && focused[key]) {
if (!this.relatedTelemetry[key].comparisonFunction(latest[key], focused[key])) {
isFresh = false;
}
} else {
isFresh = false;
}
}
} else {
isFresh = false;
}
}
return isFresh;
}
},
watch: {
focusedImageIndex() {
this.trackDuration();
this.resetAgeCSS();
this.updateRelatedTelemetryForFocusedImage();
this.getImageNaturalDimensions();
}
},
mounted() {
async mounted() {
// listen
this.openmct.time.on('bounds', this.boundsChange);
this.openmct.time.on('timeSystem', this.timeSystemChange);
@@ -212,8 +325,14 @@ export default {
// set
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
this.imageHints = { ...this.metadata.valuesForHints(['image'])[0] };
this.durationFormatter = this.getFormatter(this.timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER);
this.imageFormatter = this.openmct.telemetry.getValueFormatter(this.metadata.valuesForHints(['image'])[0]);
this.imageFormatter = this.openmct.telemetry.getValueFormatter(this.imageHints);
// related telemetry keys
this.spacecraftKeys = ['heading', 'roll', 'pitch'];
this.cameraKeys = ['cameraPan', 'cameraTilt'];
this.sunKeys = ['sunOrientation'];
// initialize
this.timeKey = this.timeSystem.key;
@@ -222,6 +341,18 @@ export default {
// kickoff
this.subscribe();
this.requestHistory();
// related telemetry
await this.initializeRelatedTelemetry();
this.updateRelatedTelemetryForFocusedImage();
this.trackLatestRelatedTelemetry();
// for scrolling through images quickly and resizing the object view
_.debounce(this.updateRelatedTelemetryForFocusedImage, 400);
_.debounce(this.resizeImageContainer, 400);
this.imageContainerResizeObserver = new ResizeObserver(this.resizeImageContainer);
this.imageContainerResizeObserver.observe(this.$refs.focusedImage);
},
updated() {
this.scrollToRight();
@@ -232,12 +363,115 @@ export default {
delete this.unsubscribe;
}
this.imageContainerResizeObserver.disconnect();
if (this.relatedTelemetry.hasRelatedTelemetry) {
this.relatedTelemetry.destroy();
}
this.stopDurationTracking();
this.openmct.time.off('bounds', this.boundsChange);
this.openmct.time.off('timeSystem', this.timeSystemChange);
this.openmct.time.off('clock', this.clockChange);
// unsubscribe from related telemetry
if (this.relatedTelemetry.hasRelatedTelemetry) {
for (let key of this.relatedTelemetry.keys) {
if (this.relatedTelemetry[key].unsubscribe) {
this.relatedTelemetry[key].unsubscribe();
}
}
}
},
methods: {
async initializeRelatedTelemetry() {
this.relatedTelemetry = new RelatedTelemetry(
this.openmct,
this.domainObject,
[...this.spacecraftKeys, ...this.cameraKeys, ...this.sunKeys]
);
if (this.relatedTelemetry.hasRelatedTelemetry) {
await this.relatedTelemetry.load();
}
},
async getMostRecentRelatedTelemetry(key, targetDatum) {
if (!this.relatedTelemetry.hasRelatedTelemetry) {
throw new Error(`${this.domainObject.name} does not have any related telemetry`);
}
if (!this.relatedTelemetry[key]) {
throw new Error(`${key} does not exist on related telemetry`);
}
let mostRecent;
let valueKey = this.relatedTelemetry[key].historical.valueKey;
let valuesOnTelemetry = this.relatedTelemetry[key].hasTelemetryOnDatum;
if (valuesOnTelemetry) {
mostRecent = targetDatum[valueKey];
if (mostRecent) {
return mostRecent;
} else {
console.warn(`Related Telemetry for ${key} does NOT exist on this telemetry datum as configuration implied.`);
return;
}
}
mostRecent = await this.relatedTelemetry[key].requestLatestFor(targetDatum);
return mostRecent[valueKey];
},
// will subscribe to data for this key if not already done
subscribeToDataForKey(key) {
if (this.relatedTelemetry[key].isSubscribed) {
return;
}
if (this.relatedTelemetry[key].realtimeDomainObject) {
this.relatedTelemetry[key].unsubscribe = this.openmct.telemetry.subscribe(
this.relatedTelemetry[key].realtimeDomainObject, datum => {
this.relatedTelemetry[key].listeners.forEach(callback => {
callback(datum);
});
}
);
this.relatedTelemetry[key].isSubscribed = true;
}
},
async updateRelatedTelemetryForFocusedImage() {
if (!this.relatedTelemetry.hasRelatedTelemetry || !this.focusedImage) {
return;
}
// set data ON image telemetry as well as in focusedImageRelatedTelemetry
for (let key of this.relatedTelemetry.keys) {
if (this.relatedTelemetry[key] && this.relatedTelemetry[key].historical) {
let valuesOnTelemetry = this.relatedTelemetry[key].hasTelemetryOnDatum;
let value = await this.getMostRecentRelatedTelemetry(key, this.focusedImage);
if (!valuesOnTelemetry) {
this.$set(this.imageHistory[this.focusedImageIndex], key, value); // manually add to telemetry
}
this.$set(this.focusedImageRelatedTelemetry, key, value);
}
}
},
trackLatestRelatedTelemetry() {
[...this.spacecraftKeys, ...this.cameraKeys, ...this.sunKeys].forEach(key => {
if (this.relatedTelemetry[key] && this.relatedTelemetry[key].subscribe) {
this.relatedTelemetry[key].subscribe((datum) => {
let valueKey = this.relatedTelemetry[key].realtime.valueKey;
this.$set(this.latestRelatedTelemetry, key, datum[valueKey]);
});
}
});
},
focusElement() {
this.$el.focus();
},
@@ -358,6 +592,7 @@ export default {
this.requestCount++;
const requestId = this.requestCount;
this.imageHistory = [];
let data = await this.openmct.telemetry
.request(this.domainObject, bounds) || [];
@@ -509,6 +744,25 @@ export default {
},
isLeftOrRightArrowKey(keyCode) {
return [ARROW_RIGHT, ARROW_LEFT].includes(keyCode);
},
getImageNaturalDimensions() {
this.focusedImageNaturalAspectRatio = undefined;
const img = this.$refs.focusedImage;
// TODO - should probably cache this
img.addEventListener('load', () => {
this.focusedImageNaturalAspectRatio = img.naturalWidth / img.naturalHeight;
}, { once: true });
},
resizeImageContainer() {
if (this.$refs.focusedImage.clientWidth !== this.imageContainerWidth) {
this.imageContainerWidth = this.$refs.focusedImage.clientWidth;
}
if (this.$refs.focusedImage.clientHeight !== this.imageContainerHeight) {
this.imageContainerHeight = this.$refs.focusedImage.clientHeight;
}
}
}
};

View File

@@ -0,0 +1,162 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
function copyRelatedMetadata(metadata) {
let compare = metadata.comparisonFunction;
let copiedMetadata = JSON.parse(JSON.stringify(metadata));
copiedMetadata.comparisonFunction = compare;
return copiedMetadata;
}
export default class RelatedTelemetry {
constructor(openmct, domainObject, telemetryKeys) {
this._openmct = openmct;
this._domainObject = domainObject;
let metadata = this._openmct.telemetry.getMetadata(this._domainObject);
let imageHints = metadata.valuesForHints(['image'])[0];
this.hasRelatedTelemetry = imageHints.relatedTelemetry !== undefined;
if (this.hasRelatedTelemetry) {
this.keys = telemetryKeys;
this._timeFormatter = undefined;
this._timeSystemChange(this._openmct.time.timeSystem());
// grab related telemetry metadata
for (let key of this.keys) {
if (imageHints.relatedTelemetry[key]) {
this[key] = copyRelatedMetadata(imageHints.relatedTelemetry[key]);
}
}
this.load = this.load.bind(this);
this._parseTime = this._parseTime.bind(this);
this._timeSystemChange = this._timeSystemChange.bind(this);
this.destroy = this.destroy.bind(this);
this._openmct.time.on('timeSystem', this._timeSystemChange);
}
}
async load() {
if (!this.hasRelatedTelemetry) {
throw new Error('This domain object does not have related telemetry, use "hasRelatedTelemetry" to check before loading.');
}
await Promise.all(
this.keys.map(async (key) => {
if (this[key].historical) {
await this._initializeHistorical(key);
}
if (this[key].realtime && this[key].realtime.telemetryObjectId) {
await this._intializeRealtime(key);
}
})
);
}
async _initializeHistorical(key) {
if (this[key].historical.telemetryObjectId) {
this[key].historicalDomainObject = await this._openmct.objects.get(this[key].historical.telemetryObjectId);
this[key].requestLatestFor = async (datum) => {
const options = {
start: this._openmct.time.bounds().start,
end: this._parseTime(datum),
strategy: 'latest'
};
let results = await this._openmct.telemetry
.request(this[key].historicalDomainObject, options);
return results[results.length - 1];
};
} else {
this[key].historical.hasTelemetryOnDatum = true;
}
}
async _intializeRealtime(key) {
this[key].realtimeDomainObject = await this._openmct.objects.get(this[key].realtime.telemetryObjectId);
this[key].listeners = [];
this[key].subscribe = (callback) => {
if (!this[key].isSubscribed) {
this._subscribeToDataForKey(key);
}
if (!this[key].listeners.includes(callback)) {
this[key].listeners.push(callback);
return () => {
this[key].listeners.remove(callback);
};
} else {
return () => {};
}
};
}
_subscribeToDataForKey(key) {
if (this[key].isSubscribed) {
return;
}
if (this[key].realtimeDomainObject) {
this[key].unsubscribe = this._openmct.telemetry.subscribe(
this[key].realtimeDomainObject, datum => {
this[key].listeners.forEach(callback => {
callback(datum);
});
}
);
this[key].isSubscribed = true;
}
}
_parseTime(datum) {
return this._timeFormatter.parse(datum);
}
_timeSystemChange(system) {
let key = system.key;
let metadata = this._openmct.telemetry.getMetadata(this._domainObject);
let metadataValue = metadata.value(key) || { format: key };
this._timeFormatter = this._openmct.telemetry.getValueFormatter(metadataValue);
}
destroy() {
this._openmct.time.off('timeSystem', this._timeSystemChange);
for (let key of this.keys) {
if (this[key].unsubscribe) {
this[key].unsubscribe();
}
}
}
}

View File

@@ -23,6 +23,7 @@
background-color: $colorPlotBg;
border: 1px solid transparent;
flex: 1 1 auto;
height: 0;
&.unnsynced{
@include sUnsynced();
@@ -30,10 +31,9 @@
}
&__image {
@include abs(); // Safari fix
background-position: center;
background-repeat: no-repeat;
background-size: contain;
height: 100%;
width: 100%;
object-fit: contain;
}
}
@@ -71,13 +71,14 @@
}
&__age {
border-radius: $controlCr;
border-radius: $smallCr;
display: flex;
flex-shrink: 0;
align-items: baseline;
padding: 1px $interiorMarginSm;
align-items: center;
padding: 2px $interiorMarginSm;
&:before {
font-size: 0.9em;
opacity: 0.5;
margin-right: $interiorMarginSm;
}
@@ -86,8 +87,9 @@
&--new {
// New imagery
$bgColor: $colorOk;
color: $colorOkFg;
background: rgba($bgColor, 0.5);
@include flash($animName: flashImageAge, $dur: 250ms, $valStart: rgba($colorOk, 0.7), $valEnd: rgba($colorOk, 0));
@include flash($animName: flashImageAge, $iter: 2, $dur: 250ms, $valStart: rgba($colorOk, 0.7), $valEnd: rgba($colorOk, 0));
}
&__thumbs-wrapper {

View File

@@ -1,3 +1,25 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import ImageryViewProvider from './ImageryViewProvider';
export default function () {

View File

@@ -37,7 +37,7 @@ function getImageInfo(doc) {
let imageElement = doc.querySelectorAll(MAIN_IMAGE_CLASS)[0];
let timestamp = imageElement.dataset.openmctImageTimestamp;
let identifier = imageElement.dataset.openmctObjectKeystring;
let url = imageElement.style.backgroundImage;
let url = imageElement.src;
return {
timestamp,
@@ -70,7 +70,7 @@ function generateTelemetry(start, count) {
return telemetry;
}
describe("The Imagery View Layout", () => {
fdescribe("The Imagery View Layout", () => {
const imageryKey = 'example.imagery';
const START = Date.now();
const COUNT = 10;

View File

@@ -17,6 +17,7 @@
@import "../plugins/folderView/components/list-item.scss";
@import "../plugins/folderView/components/list-view.scss";
@import "../plugins/imagery/components/imagery-view-layout.scss";
@import "../plugins/imagery/components/Compass/compass.scss";
@import "../plugins/telemetryTable/components/table-row.scss";
@import "../plugins/telemetryTable/components/table-footer-indicator.scss";
@import "../plugins/tabs/components/tabs.scss";