Compare commits
8 Commits
omm-r5.1.0
...
compass-ro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55b8a4142c | ||
|
|
622e6044a4 | ||
|
|
2aa757c6b7 | ||
|
|
a350c8e584 | ||
|
|
0c111f5fa2 | ||
|
|
a82e78365d | ||
|
|
0476466441 | ||
|
|
ae623b8552 |
@@ -275,7 +275,7 @@ function pointForTimestamp(timestamp, name, imageSamples, delay) {
|
||||
local: Math.floor(timestamp / delay) * delay,
|
||||
url,
|
||||
sunOrientation: getCompassValues(0, 360),
|
||||
cameraPan: getCompassValues(0, 360),
|
||||
cameraAzimuth: getCompassValues(0, 360),
|
||||
heading: getCompassValues(0, 360),
|
||||
transformations: navCamTransformations,
|
||||
imageDownloadName
|
||||
|
||||
@@ -26,18 +26,23 @@
|
||||
:style="`width: 100%; height: 100%`"
|
||||
>
|
||||
<CompassHUD
|
||||
v-if="showCompassHUD"
|
||||
:sun-heading="sunHeading"
|
||||
:camera-angle-of-view="cameraAngleOfView"
|
||||
:camera-pan="cameraPan"
|
||||
:heading="heading"
|
||||
:camera-azimuth="cameraAzimuth"
|
||||
:transformations="transformations"
|
||||
:has-gimble="hasGimble"
|
||||
:normalized-camera-azimuth="normalizedCameraAzimuth"
|
||||
:sun-heading="sunHeading"
|
||||
/>
|
||||
<CompassRose
|
||||
v-if="showCompassRose"
|
||||
:camera-pan="cameraPan"
|
||||
:camera-angle-of-view="cameraAngleOfView"
|
||||
:heading="heading"
|
||||
:sized-image-dimensions="sizedImageDimensions"
|
||||
:sun-heading="sunHeading"
|
||||
:camera-azimuth="cameraAzimuth"
|
||||
:transformations="transformations"
|
||||
:has-gimble="hasGimble"
|
||||
:normalized-camera-azimuth="normalizedCameraAzimuth"
|
||||
:sun-heading="sunHeading"
|
||||
:sized-image-dimensions="sizedImageDimensions"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -45,6 +50,7 @@
|
||||
<script>
|
||||
import CompassHUD from './CompassHUD.vue';
|
||||
import CompassRose from './CompassRose.vue';
|
||||
import { rotate } from './utils';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -62,11 +68,14 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showCompassHUD() {
|
||||
return this.hasCameraPan && this.cameraAngleOfView > 0;
|
||||
hasGimble() {
|
||||
return this.cameraAzimuth !== undefined;
|
||||
},
|
||||
showCompassRose() {
|
||||
return (this.hasCameraPan || this.hasHeading) && this.cameraAngleOfView > 0;
|
||||
// compass ordinal orientation of camera
|
||||
normalizedCameraAzimuth() {
|
||||
return this.hasGimble
|
||||
? rotate(this.cameraAzimuth)
|
||||
: rotate(this.heading, -this.transformations.rotation || 0);
|
||||
},
|
||||
// horizontal rotation from north in degrees
|
||||
heading() {
|
||||
@@ -80,14 +89,11 @@ export default {
|
||||
return this.image.sunOrientation;
|
||||
},
|
||||
// horizontal rotation from north in degrees
|
||||
cameraPan() {
|
||||
cameraAzimuth() {
|
||||
return this.image.cameraPan;
|
||||
},
|
||||
hasCameraPan() {
|
||||
return this.cameraPan !== undefined;
|
||||
},
|
||||
cameraAngleOfView() {
|
||||
return this.transformations?.cameraAngleOfView;
|
||||
return this.transformations.cameraAngleOfView;
|
||||
},
|
||||
transformations() {
|
||||
return this.image.transformations;
|
||||
|
||||
@@ -94,17 +94,33 @@ const COMPASS_POINTS = [
|
||||
|
||||
export default {
|
||||
props: {
|
||||
cameraAngleOfView: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
heading: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
cameraAzimuth: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
transformations: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
hasGimble: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
normalizedCameraAzimuth: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
sunHeading: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
cameraAngleOfView: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
cameraPan: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -130,10 +146,13 @@ export default {
|
||||
left: `${ percentage * 100 }%`
|
||||
};
|
||||
},
|
||||
cameraRotation() {
|
||||
return this.transformations?.rotation;
|
||||
},
|
||||
visibleRange() {
|
||||
return [
|
||||
rotate(this.cameraPan, -this.cameraAngleOfView / 2),
|
||||
rotate(this.cameraPan, this.cameraAngleOfView / 2)
|
||||
rotate(this.normalizedCameraAzimuth, -this.cameraAngleOfView / 2),
|
||||
rotate(this.normalizedCameraAzimuth, this.cameraAngleOfView / 2)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,6 @@
|
||||
:style="sunHeadingStyle"
|
||||
/>
|
||||
|
||||
<!-- Camera FOV -->
|
||||
<mask
|
||||
id="mask2"
|
||||
class="c-cr__cam-fov-l-mask"
|
||||
@@ -117,10 +116,10 @@
|
||||
class="cr-vrover"
|
||||
:style="camAngleAndPositionStyle"
|
||||
>
|
||||
<!-- Equipment body. Rotates relative to the camera pan value for cams that gimbal. -->
|
||||
<!-- Equipment body. Rotates relative to the camera pan value for cameras that gimble. -->
|
||||
<path
|
||||
class="cr-vrover__body"
|
||||
:style="camGimbalAngleStyle"
|
||||
:style="gimbledCameraPanStyle"
|
||||
x
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
@@ -128,6 +127,7 @@
|
||||
/>
|
||||
</g>
|
||||
|
||||
<!-- Camera FOV -->
|
||||
<g
|
||||
class="c-cr__cam-fov"
|
||||
>
|
||||
@@ -160,7 +160,7 @@
|
||||
<!-- NSEW and ticks -->
|
||||
<g
|
||||
class="c-cr__nsew"
|
||||
:style="compassRoseStyle"
|
||||
:style="compassDialStyle"
|
||||
>
|
||||
<g class="c-cr__ticks-major">
|
||||
<path d="M50 3L43 10H57L50 3Z" />
|
||||
@@ -259,23 +259,32 @@ import { throttle } from 'lodash';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
cameraAngleOfView: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
heading: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default() {
|
||||
return 0;
|
||||
}
|
||||
required: true
|
||||
},
|
||||
sunHeading: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
cameraPan: {
|
||||
cameraAzimuth: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
transformations: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
hasGimble: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
normalizedCameraAzimuth: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
sunHeading: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
sizedImageDimensions: {
|
||||
@@ -289,18 +298,6 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
cameraHeading() {
|
||||
return this.cameraPan ?? this.heading;
|
||||
},
|
||||
cameraAngleOfView() {
|
||||
const cameraAngleOfView = this.transformations?.cameraAngleOfView;
|
||||
|
||||
if (!cameraAngleOfView) {
|
||||
console.warn('No Camera Angle of View provided');
|
||||
}
|
||||
|
||||
return cameraAngleOfView;
|
||||
},
|
||||
camAngleAndPositionStyle() {
|
||||
const translateX = this.transformations?.translateX;
|
||||
const translateY = this.transformations?.translateY;
|
||||
@@ -309,18 +306,22 @@ export default {
|
||||
|
||||
return { transform: `translate(${translateX}%, ${translateY}%) rotate(${rotation}deg) scale(${scale})` };
|
||||
},
|
||||
camGimbalAngleStyle() {
|
||||
const rotation = rotate(this.heading);
|
||||
gimbledCameraPanStyle() {
|
||||
if (!this.hasGimble) {
|
||||
return;
|
||||
}
|
||||
|
||||
const gimbledCameraPan = rotate(this.normalizedCameraAzimuth, -this.heading);
|
||||
|
||||
return {
|
||||
transform: `rotate(${ rotation }deg)`
|
||||
transform: `rotate(${ -gimbledCameraPan }deg)`
|
||||
};
|
||||
},
|
||||
compassRoseStyle() {
|
||||
compassDialStyle() {
|
||||
return { transform: `rotate(${ this.north }deg)` };
|
||||
},
|
||||
north() {
|
||||
return this.lockCompass ? rotate(-this.cameraHeading) : 0;
|
||||
return this.lockCompass ? rotate(-this.normalizedCameraAzimuth) : 0;
|
||||
},
|
||||
cardinalTextRotateN() {
|
||||
return { transform: `translateY(-27%) rotate(${ -this.north }deg)` };
|
||||
@@ -348,7 +349,7 @@ export default {
|
||||
};
|
||||
},
|
||||
cameraHeadingStyle() {
|
||||
const rotation = rotate(this.north, this.cameraHeading);
|
||||
const rotation = rotate(this.north, this.normalizedCameraAzimuth);
|
||||
|
||||
return {
|
||||
transform: `rotate(${ rotation }deg)`
|
||||
|
||||
@@ -35,8 +35,15 @@ describe("The Compass component", () => {
|
||||
roll: 90,
|
||||
pitch: 90,
|
||||
cameraTilt: 100,
|
||||
cameraPan: 90,
|
||||
sunAngle: 30
|
||||
cameraAzimuth: 90,
|
||||
sunAngle: 30,
|
||||
transformations: {
|
||||
translateX: 0,
|
||||
translateY: 18,
|
||||
rotation: 0,
|
||||
scale: 0.3,
|
||||
cameraAngleOfView: 70
|
||||
}
|
||||
};
|
||||
let propsData = {
|
||||
naturalAspectRatio: 0.9,
|
||||
@@ -44,8 +51,7 @@ describe("The Compass component", () => {
|
||||
sizedImageDimensions: {
|
||||
width: 100,
|
||||
height: 100
|
||||
},
|
||||
compassRoseSizingClasses: '--rose-small --rose-min'
|
||||
}
|
||||
};
|
||||
|
||||
app = new Vue({
|
||||
@@ -54,7 +60,6 @@ describe("The Compass component", () => {
|
||||
return propsData;
|
||||
},
|
||||
template: `<Compass
|
||||
:compass-rose-sizing-classes="compassRoseSizingClasses"
|
||||
:image="image"
|
||||
:natural-aspect-ratio="naturalAspectRatio"
|
||||
:sized-image-dimensions="sizedImageDimensions"
|
||||
@@ -67,7 +72,7 @@ describe("The Compass component", () => {
|
||||
app.$destroy();
|
||||
});
|
||||
|
||||
describe("when a heading value exists on the image", () => {
|
||||
describe("when a heading value and cameraAngleOfView exists on the image", () => {
|
||||
|
||||
it("should display a compass rose", () => {
|
||||
let compassRoseElement = instance.$el.querySelector(COMPASS_ROSE_CLASS
|
||||
|
||||
@@ -430,9 +430,12 @@ export default {
|
||||
&& imageHeightAndWidth
|
||||
&& this.zoomFactor === 1
|
||||
&& this.imagePanned !== true;
|
||||
const hasCameraConfigurations = this.focusedImage?.transformations !== undefined;
|
||||
const hasHeading = this.focusedImage?.heading !== undefined;
|
||||
const hasCameraAngleOfView = this.focusedImage?.transformations?.cameraAngleOfView > 0;
|
||||
|
||||
return display && hasCameraConfigurations;
|
||||
return display
|
||||
&& hasCameraAngleOfView
|
||||
&& hasHeading;
|
||||
},
|
||||
isSpacecraftPositionFresh() {
|
||||
let isFresh = undefined;
|
||||
@@ -585,7 +588,6 @@ export default {
|
||||
focusedImageIndex() {
|
||||
this.trackDuration();
|
||||
this.resetAgeCSS();
|
||||
this.updateRelatedTelemetryForFocusedImage();
|
||||
this.getImageNaturalDimensions();
|
||||
},
|
||||
bounds() {
|
||||
@@ -771,6 +773,10 @@ export default {
|
||||
this.layers = layersMetadata;
|
||||
if (this.domainObject.configuration) {
|
||||
const persistedLayers = this.domainObject.configuration.layers;
|
||||
if (!persistedLayers) {
|
||||
return;
|
||||
}
|
||||
|
||||
layersMetadata.forEach((layer) => {
|
||||
const persistedLayer = persistedLayers.find(object => object.name === layer.name);
|
||||
if (persistedLayer) {
|
||||
@@ -957,6 +963,7 @@ export default {
|
||||
}
|
||||
|
||||
this.focusedImageIndex = index;
|
||||
this.updateRelatedTelemetryForFocusedImage();
|
||||
},
|
||||
trackDuration() {
|
||||
if (this.canTrackDuration) {
|
||||
|
||||
@@ -153,9 +153,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// forcibly reset the imageContainer size to prevent an aspect ratio distortion
|
||||
delete this.imageContainerWidth;
|
||||
delete this.imageContainerHeight;
|
||||
this.bounds = bounds; // setting bounds for ImageryView watcher
|
||||
},
|
||||
timeSystemChange() {
|
||||
|
||||
Reference in New Issue
Block a user