mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 12:27:07 +00:00
Add more layers to Map component.
This commits adds back the vessel track as well as other layers, gives the option to load both point and line versions of the plan, raw, and final sequences, and adds heatmaps showing positioning error of raw and final data relative to preplots. The implementation in this commit relies on translating the binary sequence data into JSON (for the heatmaps) which is inefficient but adequate as an initial proof of concept.
This commit is contained in:
@@ -21,9 +21,49 @@
|
||||
|
||||
<input id="lyr-nau" type="checkbox" value="nau" v-model="layerSelection"/>
|
||||
<label for="lyr-nau" title="Scan of Norway's nautical charts">Nautical charts (NO)</label>
|
||||
</form>
|
||||
|
||||
<hr class="my-2"/><hr class="my-2"/>
|
||||
<hr class="my-2"/>
|
||||
|
||||
<div class="lines-points">
|
||||
|
||||
<span>Vessel track</span>
|
||||
<label title="Show points"><v-icon small left class="mx-0">mdi-vector-point</v-icon> <input type="checkbox" value="navp" v-model="layerSelection"/></label>
|
||||
<label title="Show lines" disabled><v-icon small left class="mx-0">mdi-vector-line</v-icon> <input type="checkbox" value="navl" v-model="layerSelection"/></label>
|
||||
<label><!-- No heatmap available --></label>
|
||||
|
||||
<span>Sail lines</span>
|
||||
<label title="Show points"><v-icon small left class="mx-0">mdi-vector-point</v-icon> <input type="checkbox" value="pslp" v-model="layerSelection"/></label>
|
||||
<label title="Show lines" disabled><v-icon small left class="mx-0">mdi-vector-line</v-icon> <input type="checkbox" value="psll" v-model="layerSelection"/></label>
|
||||
<label><!-- No heatmap available --></label>
|
||||
|
||||
<span>Preplots</span>
|
||||
<label title="Show points"><v-icon small left class="mx-0">mdi-vector-point</v-icon> <input type="checkbox" value="pplp" v-model="layerSelection"/></label>
|
||||
<label title="Show lines"><v-icon small left class="mx-0">mdi-vector-line</v-icon> <input type="checkbox" value="ppll" v-model="layerSelection"/></label>
|
||||
<label><!-- No heatmap available --></label>
|
||||
|
||||
<span>Plan</span>
|
||||
<label title="Show points"><v-icon small left class="mx-0">mdi-vector-point</v-icon> <input type="checkbox" value="planp" v-model="layerSelection"/></label>
|
||||
<label title="Show lines"><v-icon small left class="mx-0">mdi-vector-line</v-icon> <input type="checkbox" value="planl" v-model="layerSelection"/></label>
|
||||
<label><!-- No heatmap available --></label>
|
||||
|
||||
<span>Raw data</span>
|
||||
<label title="Show points"><v-icon small left class="mx-0">mdi-vector-point</v-icon> <input type="checkbox" value="seqrp" v-model="layerSelection"/></label>
|
||||
<label title="Show lines"><v-icon small left class="mx-0">mdi-vector-line</v-icon> <input type="checkbox" value="seqrl" v-model="layerSelection"/></label>
|
||||
<label title="Show position error"><v-icon small left class="mx-0">mdi-dots-grid</v-icon> <input type="checkbox" value="seqrh" v-model="layerSelection"/></label>
|
||||
|
||||
<span>Final data</span>
|
||||
<label title="Show points"><v-icon small left class="mx-0">mdi-vector-point</v-icon> <input type="checkbox" value="seqfp" v-model="layerSelection"/></label>
|
||||
<label title="Show lines"><v-icon small left class="mx-0">mdi-vector-line</v-icon> <input type="checkbox" value="seqfl" v-model="layerSelection"/></label>
|
||||
<label title="Show position error"><v-icon small left class="mx-0">mdi-dots-grid</v-icon> <input type="checkbox" value="seqfh" v-model="layerSelection"/></label>
|
||||
|
||||
<span>Events</span>
|
||||
<label title="Show points"><v-icon small left class="mx-0">mdi-vector-point</v-icon> <input type="checkbox" value="log" v-model="layerSelection"/></label>
|
||||
<label><!-- No lines available --></label>
|
||||
<label><!-- No heatmap available --></label>
|
||||
|
||||
</div>
|
||||
<!--
|
||||
<input id="lyr-psl" type="checkbox" value="psl" v-model="layerSelection"/>
|
||||
<label for="lyr-psl" title="Vessel preplots">Sail lines</label>
|
||||
|
||||
@@ -36,6 +76,9 @@
|
||||
<input id="lyr-preplots" type="checkbox" value="preplots" v-model="layerSelection"/>
|
||||
<label for="lyr-preplots" title="Shotpoint deviation from preplot position">Preplot error</label>
|
||||
|
||||
<input id="lyr-peh" type="checkbox" value="peh" v-model="layerSelection"/>
|
||||
<label for="lyr-peh" title="Shotpoint deviation from preplot position">Preplot error (heatmap)</label>
|
||||
|
||||
<input id="lyr-seq" type="checkbox" value="seq" v-model="layerSelection"/>
|
||||
<label for="lyr-seq" title="Raw and/or final shot positions">Sequence data</label>
|
||||
|
||||
@@ -44,13 +87,14 @@
|
||||
|
||||
<input id="lyr-nav" type="checkbox" value="nav" v-model="layerSelection"/>
|
||||
<label for="lyr-nav" title="Vessel track">Navigation trail</label>
|
||||
|
||||
-->
|
||||
<form>
|
||||
<template v-if="crosshairsPosition.length">
|
||||
<input id="lyr-crosshairs" type="checkbox" value="crosshairs" v-model="layerSelection"/>
|
||||
<label for="lyr-crosshairs" title="Show or hide the crosshairs position marker">Crosshairs marker</label>
|
||||
</template>
|
||||
</form>
|
||||
|
||||
<!--
|
||||
<h3 class="mt-3" title="At least one of raw or final will always be selected">Sequence data</h3>
|
||||
<form>
|
||||
<input id="sd-raw" type="checkbox" value="R" v-model="sequenceDataTypes"/>
|
||||
@@ -58,6 +102,7 @@
|
||||
<input id="sd-final" type="checkbox" value="F" v-model="sequenceDataTypes"/>
|
||||
<label for="sd-final">Show final</label>
|
||||
</form>
|
||||
-->
|
||||
|
||||
<!-- QC data: This section is meant to show (some) QC results in a graphical way,
|
||||
as 3D columns with lengths proportional to the QC values. Not implemented
|
||||
@@ -209,6 +254,16 @@
|
||||
grid-template-columns: 36px 1fr;
|
||||
}
|
||||
|
||||
.map-overlay-inner .lines-points {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(auto, 1fr) 36px 36px 36px;
|
||||
grid-column-gap: 4px;
|
||||
}
|
||||
|
||||
.map-overlay-inner .lines-points :nth-child(4n+1) {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.map-overlay input[type=text] {
|
||||
background-color: white;
|
||||
border: 1px solid black;
|
||||
@@ -255,12 +310,14 @@ import { markdown, markdownInline } from '@/lib/markdown';
|
||||
|
||||
import { Deck, WebMercatorViewport, FlyToInterpolator, CompositeLayer } from '@deck.gl/core';
|
||||
import { GeoJsonLayer, LineLayer, BitmapLayer, ScatterplotLayer, IconLayer } from '@deck.gl/layers';
|
||||
import { TileLayer } from '@deck.gl/geo-layers';
|
||||
import {HeatmapLayer} from '@deck.gl/aggregation-layers';
|
||||
import { TileLayer, MVTLayer } from '@deck.gl/geo-layers';
|
||||
import * as d3a from 'd3-array';
|
||||
|
||||
//import { json } from 'd3-fetch';
|
||||
|
||||
import { SequenceDataLayer } from '@/lib/deck.gl';
|
||||
import { unbundle, unpack, isLittleEndian } from '@/lib/binary';
|
||||
import { unbundle, unpack, toJSON, isLittleEndian } from '@/lib/binary';
|
||||
|
||||
// Important info about performance:
|
||||
// https://deck.gl/docs/developer-guide/performance#supply-attributes-directly
|
||||
@@ -304,7 +361,28 @@ export default {
|
||||
filterText: "",
|
||||
filterVisible: false,
|
||||
|
||||
error: null
|
||||
error: null,
|
||||
/*
|
||||
layerDefinitions: [
|
||||
{
|
||||
id: "osm",
|
||||
name: "OpenStreetMap"
|
||||
},
|
||||
{
|
||||
id: "sea",
|
||||
name: "OpenSeaMap"
|
||||
},
|
||||
{
|
||||
id: "nau",
|
||||
name: "Nautical charts (NO)",
|
||||
title: "Scan of Norway's nautical charts"
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
|
||||
|
||||
]
|
||||
*/
|
||||
};
|
||||
},
|
||||
|
||||
@@ -317,6 +395,20 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
sequenceDataRaw () {
|
||||
return {
|
||||
tstamp: this.sequenceDataTStamp,
|
||||
sequences: this.sequenceDataElements.filter(i => i.type == "R")
|
||||
};
|
||||
},
|
||||
|
||||
sequenceDataFinal () {
|
||||
return {
|
||||
tstamp: this.sequenceDataTStamp,
|
||||
sequences: this.sequenceDataElements.filter(i => i.type == "F")
|
||||
};
|
||||
},
|
||||
|
||||
sequenceDataPostplots () {
|
||||
const fn = i => i.type != "P" && this.sequenceDataTypes.includes(i.type);
|
||||
return {
|
||||
@@ -325,6 +417,18 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
fullProspectRaw () {
|
||||
// Get raw data, so type = "R"
|
||||
const sequences = this.sequenceDataElements.filter( i => i.type == "R" );
|
||||
return [...sequences.map( i => toJSON(i.data) )].flat();
|
||||
},
|
||||
|
||||
fullProspectFinal () {
|
||||
// Get raw data, so type = "R"
|
||||
const sequences = this.sequenceDataElements.filter( i => i.type == "F" );
|
||||
return [...sequences.map( i => toJSON(i.data) )].flat();
|
||||
},
|
||||
|
||||
...mapGetters(['user', 'loading', 'serverEvent', 'lineName', 'serverEvent']),
|
||||
...mapState({projectSchema: state => state.project.projectSchema})
|
||||
},
|
||||
@@ -398,13 +502,16 @@ export default {
|
||||
},
|
||||
|
||||
zoomReset () {
|
||||
// FIXME just to test, we calculate from the sequence layer
|
||||
if (deck && deck.layerManager) {
|
||||
const sl = deck.layerManager.getLayers().find(l => l.id == "seq");
|
||||
if (deck) {
|
||||
const bounds = this.sequencesBBox();
|
||||
const initialViewState = {...this.viewStateDefaults, ...sl.context.viewport.fitBounds(bounds)};
|
||||
initialViewState.transitionDuration = 500;
|
||||
deck.setProps({initialViewState});
|
||||
if (bounds) {
|
||||
const layer = deck.layerManager.layers[0]; // Get the first layer we come across
|
||||
const initialViewState = {...this.viewStateDefaults, ...layer.context.viewport.fitBounds(bounds)};
|
||||
initialViewState.transitionDuration = 500;
|
||||
deck.setProps({initialViewState});
|
||||
}
|
||||
} else {
|
||||
console.warn("Unable to calculate bounding box");
|
||||
}
|
||||
},
|
||||
|
||||
@@ -430,27 +537,28 @@ export default {
|
||||
|
||||
sequencesBBox (margin = 0.1) {
|
||||
let [ λ0, φ0, λ1, φ1 ] = [ +Infinity, +Infinity, -Infinity, -Infinity ];
|
||||
if (deck && deck.layerManager) {
|
||||
const sl = deck.layerManager.getLayers().find(l => l.id == "seq");
|
||||
if (sl) {
|
||||
const positions = sl.getSubLayers().map(l => l.props.data.attributes.getPosition.value);
|
||||
for (const position of positions) {
|
||||
for (let n=0; n<position.length; n+=2) {
|
||||
const λ = position[n];
|
||||
const φ = position[n+1];
|
||||
λ0 = Math.min(λ0, λ);
|
||||
φ0 = Math.min(φ0, φ);
|
||||
λ1 = Math.max(λ1, λ);
|
||||
φ1 = Math.max(φ1, φ);
|
||||
}
|
||||
}
|
||||
const δλ = λ1 - λ0;
|
||||
const δφ = φ1 - φ0;
|
||||
const mλ = δλ * margin;
|
||||
const mφ = δφ * margin;
|
||||
|
||||
return [ [λ0-mλ, φ0-mφ], [λ1+mλ, φ1+mφ] ];
|
||||
// FIXME Temporary fix to get this working again, but this.fullProspectRaw /
|
||||
// this.fullProspectFinal are not intended to remain as JSON data.
|
||||
|
||||
const data = this.fullProspectRaw ?? this.fullProspectFinal;
|
||||
|
||||
if (data) {
|
||||
for (const i of data) {
|
||||
const λ = i.longitude;
|
||||
const φ = i.latitude;
|
||||
λ0 = Math.min(λ0, λ);
|
||||
φ0 = Math.min(φ0, φ);
|
||||
λ1 = Math.max(λ1, λ);
|
||||
φ1 = Math.max(φ1, φ);
|
||||
}
|
||||
|
||||
const δλ = λ1 - λ0;
|
||||
const δφ = φ1 - φ0;
|
||||
const mλ = δλ * margin;
|
||||
const mφ = δφ * margin;
|
||||
|
||||
return [ [λ0-mλ, φ0-mφ], [λ1+mλ, φ1+mφ] ];
|
||||
}
|
||||
},
|
||||
|
||||
@@ -693,6 +801,48 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
// OSM tiles layer. Handy to make water transparent
|
||||
// but super reliable yet
|
||||
|
||||
this.layersAvailable.osm = (options = {}) => {
|
||||
return new MVTLayer({
|
||||
id: 'osm',
|
||||
data: 'https://vector.openstreetmap.org/shortbread_v1/{z}/{x}/{y}.mvt',
|
||||
minZoom: 0,
|
||||
maxZoom: 14,
|
||||
getFillColor: feature => {
|
||||
const layer = feature.properties.layerName;
|
||||
//console.log("layer =", layer, feature.properties.kind);
|
||||
switch (layer) {
|
||||
case "ocean":
|
||||
return [0, 0, 0, 0];
|
||||
case "land":
|
||||
return [ 0x54, 0x6E, 0x7A, 255 ];
|
||||
default:
|
||||
return [ 240, 240, 240, 255 ];
|
||||
}
|
||||
},
|
||||
getLineColor: feature => {
|
||||
if (feature.properties.layer === 'water') {
|
||||
return [0, 0, 0, 0]; // No outline for water
|
||||
}
|
||||
return [192, 192, 192, 255]; // Default line color for roads, etc.
|
||||
},
|
||||
getLineWidth: feature => {
|
||||
if (feature.properties.highway) {
|
||||
return feature.properties.highway === 'motorway' ? 6 : 3; // Example road widths
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
stroked: true,
|
||||
filled: true,
|
||||
pickable: true
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
this.layersAvailable.nau = (options = {}) => {
|
||||
return new TileLayer({
|
||||
@@ -720,17 +870,47 @@ export default {
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
this.layersAvailable.nav = (options = {}) => {
|
||||
return new GeoJsonLayer({
|
||||
id: 'nav',
|
||||
data: `/api/navdata/gis/line`,
|
||||
this.layersAvailable.navp = (options = {}) => {
|
||||
return new ScatterplotLayer({
|
||||
id: 'navp',
|
||||
data: `/api/navdata?limit=10000&offset=300000`,
|
||||
getPosition: (d) => ([d.longitude, d.latitude]),
|
||||
getRadius: d => (d.speed),
|
||||
radiusScale: 1,
|
||||
lineWidthMinPixels: 2,
|
||||
getFillColor: d => d.guns
|
||||
? d.lineStatus == "online"
|
||||
? [0xaa, 0x00, 0xff] // Online
|
||||
: [0xd5, 0x00, 0xf9] // Soft start or guns otherwise active
|
||||
: [0xea, 0x80, 0xfc], // Offline, guns inactive
|
||||
getLineColor: [127, 65, 90],
|
||||
getColor: [ 255, 0, 0 ],
|
||||
getPointRadius: 12,
|
||||
radiusUnits: "pixels",
|
||||
pointRadiusMinPixels: 4,
|
||||
stroked: false,
|
||||
filled: true,
|
||||
pickable: true,
|
||||
...options
|
||||
})
|
||||
};
|
||||
|
||||
this.layersAvailable.navl = (options = {}) => {
|
||||
return new LineLayer({
|
||||
id: 'navl',
|
||||
data: `/api/navdata`,
|
||||
lineWidthMinPixels: 2,
|
||||
getLineColor: (d) => d.properties.ntba ? [240, 248, 255, 200] : [85, 170, 255, 200],
|
||||
getSourcePosition: (obj, i) => i.index < i.data?.length ? [i.data[i.index]?.longitude, i.data[i.index]?.latitude] : null,
|
||||
getTargetPosition: (obj, i) => i.index < i.data?.length ? [i.data[i.index+1]?.longitude, i.data[i.index+1]?.latitude] : null,
|
||||
getLineWidth: 3,
|
||||
getPointRadius: 2,
|
||||
radiusUnits: "pixels",
|
||||
pointRadiusMinPixels: 2,
|
||||
pickable: true,
|
||||
...options
|
||||
})
|
||||
};
|
||||
*/
|
||||
|
||||
this.layersAvailable.sea = (options = {}) => {
|
||||
return new TileLayer({
|
||||
@@ -770,9 +950,9 @@ export default {
|
||||
})
|
||||
};
|
||||
|
||||
this.layersAvailable.psl = (options = {}) => {
|
||||
this.layersAvailable.psll = (options = {}) => {
|
||||
return new GeoJsonLayer({
|
||||
id: 'psl',
|
||||
id: 'psll',
|
||||
data: `/api/project/${this.$route.params.project}/gis/preplot/line?class=V`,
|
||||
lineWidthMinPixels: 1,
|
||||
getLineColor: (d) => d.properties.ntba ? [240, 248, 255, 200] : [85, 170, 255, 200],
|
||||
@@ -785,9 +965,9 @@ export default {
|
||||
})
|
||||
};
|
||||
|
||||
this.layersAvailable.ppl = (options = {}) => {
|
||||
this.layersAvailable.ppll = (options = {}) => {
|
||||
return new GeoJsonLayer({
|
||||
id: 'ppl',
|
||||
id: 'ppll',
|
||||
data: `/api/project/${this.$route.params.project}/gis/preplot/line`,
|
||||
lineWidthMinPixels: 1,
|
||||
getLineColor: (d) => d.properties.ntba ? [240, 248, 255, 200] : [85, 170, 255, 200],
|
||||
@@ -800,7 +980,7 @@ export default {
|
||||
})
|
||||
};
|
||||
|
||||
this.layersAvailable.plan = (options = {}) => {
|
||||
this.layersAvailable.planl = (options = {}) => {
|
||||
return new LineLayer({
|
||||
id: 'plan',
|
||||
data: `/api/project/${this.$route.params.project}/plan`,
|
||||
@@ -819,24 +999,91 @@ export default {
|
||||
})
|
||||
};
|
||||
|
||||
this.layersAvailable.preplots = (options = {}) => {
|
||||
this.layersAvailable.seqrl = (options = {}) => {
|
||||
return new GeoJsonLayer({
|
||||
id: 'seqrl',
|
||||
data: `/api/project/${this.$route.params.project}/gis/raw/line`,
|
||||
lineWidthMinPixels: 1,
|
||||
getLineColor: (d) => d.properties.ntbp ? [0xe6, 0x51, 0x00, 200] : [0xff, 0x98, 0x00, 200],
|
||||
getLineWidth: 1,
|
||||
getPointRadius: 2,
|
||||
radiusUnits: "pixels",
|
||||
pointRadiusMinPixels: 2,
|
||||
pickable: true,
|
||||
...options
|
||||
})
|
||||
};
|
||||
|
||||
this.layersAvailable.seqfl = (options = {}) => {
|
||||
return new GeoJsonLayer({
|
||||
id: 'seqfl',
|
||||
data: `/api/project/${this.$route.params.project}/gis/final/line`,
|
||||
lineWidthMinPixels: 1,
|
||||
getLineColor: (d) => d.properties.pending ? [0xa7, 0xff, 0xab, 200] : [0x00, 0x96, 0x88, 200],
|
||||
getLineWidth: 1,
|
||||
getPointRadius: 2,
|
||||
radiusUnits: "pixels",
|
||||
pointRadiusMinPixels: 2,
|
||||
pickable: true,
|
||||
...options
|
||||
})
|
||||
};
|
||||
|
||||
this.layersAvailable.pplp = (options = {}) => {
|
||||
return new SequenceDataLayer({
|
||||
id: 'preplots',
|
||||
id: 'pplp',
|
||||
data: this.sequenceDataPreplots,
|
||||
pickable: true,
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
this.layersAvailable.seq = (options = {}) => {
|
||||
this.layersAvailable.seqrp = (options = {}) => {
|
||||
return new SequenceDataLayer({
|
||||
id: 'seq',
|
||||
data: this.sequenceDataPostplots,
|
||||
id: 'seqrp',
|
||||
data: this.sequenceDataRaw,
|
||||
pickable: true,
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
this.layersAvailable.seqfp = (options = {}) => {
|
||||
return new SequenceDataLayer({
|
||||
id: 'seqfp',
|
||||
data: this.sequenceDataFinal,
|
||||
pickable: true,
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
this.layersAvailable.seqrh = (options = {}) => {
|
||||
return new HeatmapLayer({
|
||||
id: 'seqrh',
|
||||
data: this.fullProspectRaw,
|
||||
radiusPixels: 15,
|
||||
getPosition: d => [ d.longitude, d.latitude ],
|
||||
getWeight: d => Math.sqrt(d.Δi**2 + d.Δj**2),
|
||||
colorDomain: [2, 20],
|
||||
aggregation: "MEAN",
|
||||
pickable: false,
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
this.layersAvailable.seqfh = (options = {}) => {
|
||||
return new HeatmapLayer({
|
||||
id: 'seqfh',
|
||||
data: this.fullProspectFinal,
|
||||
radiusPixels: 15,
|
||||
getPosition: d => [ d.longitude, d.latitude ],
|
||||
getWeight: d => Math.sqrt(d.Δi**2 + d.Δj**2),
|
||||
colorDomain: [2, 20],
|
||||
aggregation: "MEAN",
|
||||
pickable: false,
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
this.layersAvailable.crosshairs = (options = {}) => {
|
||||
return new IconLayer({
|
||||
id: 'crosshairs',
|
||||
@@ -871,6 +1118,7 @@ export default {
|
||||
onWebGLInitialized: this.initLayers
|
||||
});
|
||||
|
||||
|
||||
function getTooltip (args) {
|
||||
//console.log("tooltip", args?.layer?.constructor?.layerName, args);
|
||||
if (args?.layer?.constructor?.tooltip) {
|
||||
@@ -896,7 +1144,7 @@ export default {
|
||||
return {html, style};
|
||||
}
|
||||
|
||||
} else if (args?.layer?.id == "ppl" || args?.layer?.id == "psl") {
|
||||
} else if (args?.layer?.id == "pplp" || args?.layer?.id == "pslp") {
|
||||
|
||||
const p = args?.object?.properties;
|
||||
const isSailline = args?.layer?.id == "psl";
|
||||
@@ -938,11 +1186,83 @@ export default {
|
||||
return {html, style};
|
||||
}
|
||||
|
||||
} else if (args?.layer?.id == "seqrl" || args?.layer?.id == "seqfl") {
|
||||
|
||||
let type;
|
||||
switch(args.layer.id) {
|
||||
case "seqrl":
|
||||
type = "Raw";
|
||||
break;
|
||||
case "seqfl":
|
||||
type = "Final";
|
||||
break;
|
||||
}
|
||||
|
||||
const p = args?.object?.properties;
|
||||
if (p) {
|
||||
let html = `Sequence ${p.sequence} (${type})<br/>\n`;
|
||||
html += `Line <b>${p.line}</b><br/>\n`;
|
||||
html += `${p.num_points} points (${p.missing_shots ? (p.missing_shots + " missing") : "None missing"})<br/>\n`;
|
||||
html+= `${(p.length??0).toFixed(0)} m ${(p.azimuth??0).toFixed(1)}°<br/>\n`;
|
||||
html += `${p.duration}<br/>\n`;
|
||||
html += `<b>${p.fsp}</b> @ ${p.ts0?.substring(0, 10)}<br/>\n`;
|
||||
html += `<b>${p.lsp}</b> @ ${p.ts1?.substring(0, 10)}<br/>\n`;
|
||||
if (p.ntbp) {
|
||||
html += "<b>Not to be processed</b><br/>\n";
|
||||
} else if (p.pending) {
|
||||
html += "<b>Pending</b><br/>\n";
|
||||
}
|
||||
html += "<hr/><br/>\n";
|
||||
html += markdown(p.remarks);
|
||||
|
||||
const style = { "max-width": "50ex"};
|
||||
|
||||
return {html, style};
|
||||
}
|
||||
} else if (args?.layer?.id == "navp") {
|
||||
const p = args.object;
|
||||
|
||||
if (p) {
|
||||
let html = `${p.vesselName}<br/>\n`
|
||||
+ `${p.tstamp}<br/>\n`
|
||||
+ `BSP ${(p.speed??0).toFixed(1)} kt CMG ${(p.cmg??0).toFixed(1).padStart(5, "0")}° HDG ${(p.bearing??0).toFixed(1).padStart(5, "0")}° DPT ${(p.waterDepth??0).toFixed(1)} m<br/>\n`
|
||||
+ `${p.lineStatus}<br/>\n`;
|
||||
|
||||
if (p.guns) {
|
||||
console.log(p);
|
||||
const pressure = p.guns.map( i => i[11] ); // 11 is gun pressure
|
||||
const μpress = d3a.mean(pressure);
|
||||
const σpress = d3a.deviation(pressure);
|
||||
|
||||
if (p.lineStatus && p.lineStatus != "offline") {
|
||||
html += `${p.lineName}<br/>\n`
|
||||
+ `S: ${p._sequence} L: ${p._line} P: ${p.shot}<br/>`
|
||||
+ `Source ${p.src_number} `
|
||||
+ ((p.trg_mode && p.trg_mode != "external") ? `<b>${p.trg_mode.toUpperCase()} TRIGGER</b> ` : "")
|
||||
+ `<small>FSID ${p.fsid}</small> <small>mask ${p.mask}</small><br/>\n`
|
||||
+ `Δ ${(p.avg_delta??0).toFixed(3)} ms ±${(p.std_delta??0).toFixed(3)} ms<br/>\n`
|
||||
+ `${(μpress??0).toFixed(0)} psi ±${(σpress??0).toFixed(0)} psi / ${(p.volume??0).toFixed(0)} in³<br/>\n`
|
||||
+ `along ${(p.inline??0).toFixed(1)} m / across ${(p.crossline??0).toFixed(1)} m<br/>\n`;
|
||||
} else {
|
||||
// Soft start?
|
||||
html +=
|
||||
`Source ${p.src_number} `
|
||||
+ ((p.trg_mode && p.trg_mode != "external") ? `<b>${p.trg_mode.toUpperCase()} TRIGGER</b> ` : "")
|
||||
+ `<small>mask ${p.mask}</small><br/>\n`
|
||||
+ `Δ ${(p.avg_delta??0).toFixed(3)} ms ±${(p.std_delta??0).toFixed(3)} ms<br/>\n`
|
||||
+ `${(p.manifold??0).toFixed(0)} psi / ${(p.volume??0).toFixed(0)} in³<br/>\n`
|
||||
+ `along ${(p.inline??0).toFixed(1)} m / across ${(p.crossline??0).toFixed(1)} m<br/>\n`;
|
||||
}
|
||||
}
|
||||
|
||||
const style = { "max-width": "50ex"};
|
||||
|
||||
return {html, style};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.layerSelection = [ "seq" ];
|
||||
|
||||
//this.layerSelection = [ "seq" ];
|
||||
this.getSequenceData();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user