signalk-livedepth-plugin 0.3.3 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-livedepth-plugin",
3
- "version": "0.3.3",
3
+ "version": "0.3.11",
4
4
  "description": "Build and visualise a depth map from your own soundings, live on the chart as your vessel moves.",
5
5
  "keywords": [
6
6
  "signalk-node-server-plugin",
@@ -667,10 +667,20 @@ var DEFAULT_SETTINGS = {
667
667
  enabled: true,
668
668
  source: "history",
669
669
  quality: "auto",
670
+ fullResolution: true,
671
+ vectorContours: true,
672
+ msaa: true,
673
+ fieldCells: 2048,
674
+ contourWidthPx: 1,
675
+ minorContourWidthPx: 0.75,
676
+ majorContourColor: "#000000",
677
+ minorContourColor: "#9aa4a8",
670
678
  historyWindowHours: 1,
671
679
  historyResolutionS: 0.1,
672
680
  shadeLimitMetres: 10,
673
- contourIntervalMetres: 1,
681
+ contourIntervalMetres: 1.524,
682
+ minorContourMetres: 0.3048,
683
+ fillMetres: 6,
674
684
  cellPx: 24,
675
685
  mergeTolerance: 0.15,
676
686
  maxDepthMetres: 100,
@@ -684,8 +694,13 @@ var SETTINGS_BOUNDS = {
684
694
  historyWindowHours: { min: 0.1, max: 168, step: 0.1 },
685
695
  historyResolutionS: { min: 0.01, max: 60, step: 0.01 },
686
696
  shadeLimitMetres: { min: 1, max: 200, step: 1 },
687
- contourIntervalMetres: { min: 0.5, max: 50, step: 0.5 },
697
+ contourIntervalMetres: { min: 0.3048, max: 50, step: 0.3048 },
698
+ minorContourMetres: { min: 0.3048, max: 50, step: 0.3048 },
699
+ fillMetres: { min: 0, max: 20, step: 1 },
688
700
  cellPx: { min: 4, max: 128, step: 1 },
701
+ fieldCells: { min: 256, max: 4096, step: 256 },
702
+ contourWidthPx: { min: 0.5, max: 6, step: 0.5 },
703
+ minorContourWidthPx: { min: 0.5, max: 6, step: 0.25 },
689
704
  mergeTolerance: { min: 0, max: 1, step: 0.01 },
690
705
  maxDepthMetres: { min: 1, max: 500, step: 1 },
691
706
  safetyDepthMetres: { min: 0, max: 50, step: 0.5 }
@@ -740,10 +755,22 @@ var FIELDS = [
740
755
  },
741
756
  {
742
757
  key: "contourIntervalMetres",
743
- label: "Isobath interval",
744
- hint: "Depth between isobaths.",
758
+ label: "Major isobath interval",
759
+ hint: "Depth between index isobaths; every multiple of this is a major contour.",
745
760
  depth: true
746
761
  },
762
+ {
763
+ key: "minorContourMetres",
764
+ label: "Minor isobath interval",
765
+ hint: "Depth between the minor isobaths.",
766
+ depth: true
767
+ },
768
+ {
769
+ key: "fillMetres",
770
+ label: "Fill radius",
771
+ hint: "How far a sounding fills water with no samples; measured cells keep their own depth.",
772
+ suffix: "m"
773
+ },
747
774
  {
748
775
  key: "cellPx",
749
776
  label: "Grid cell",
@@ -766,8 +793,71 @@ var FIELDS = [
766
793
  label: "Safety depth",
767
794
  hint: "Samples at or below this depth are marked individually.",
768
795
  depth: true
796
+ },
797
+ {
798
+ key: "fieldCells",
799
+ label: "Field resolution",
800
+ hint: "Depth-field cells across the view; higher resolves finer contours."
801
+ },
802
+ {
803
+ key: "contourWidthPx",
804
+ label: "Major contour width",
805
+ hint: "Major (index) isobar line width.",
806
+ suffix: "px"
807
+ },
808
+ {
809
+ key: "minorContourWidthPx",
810
+ label: "Minor contour width",
811
+ hint: "Minor isobar line width.",
812
+ suffix: "px"
769
813
  }
770
814
  ];
815
+ var TOGGLES = [
816
+ {
817
+ key: "fullResolution",
818
+ label: "Full surface resolution",
819
+ hint: "Draw the shaded surface at the display's full size instead of the quality scale (like crowd-depth)."
820
+ },
821
+ {
822
+ key: "vectorContours",
823
+ label: "Vector contours",
824
+ hint: "Draw isobars as vector lines, crisp at any zoom, instead of the per-fragment approximation."
825
+ },
826
+ {
827
+ key: "msaa",
828
+ label: "Smooth edges (MSAA)",
829
+ hint: "Antialias the WebGL surface edges; applied on the next frame."
830
+ }
831
+ ];
832
+ var COLOR_FIELDS = [
833
+ {
834
+ key: "majorContourColor",
835
+ label: "Major contour colour",
836
+ hint: "Colour of the index (major) isobars."
837
+ },
838
+ {
839
+ key: "minorContourColor",
840
+ label: "Minor contour colour",
841
+ hint: "Colour of the minor isobars."
842
+ }
843
+ ];
844
+ var GRAPHICS = [
845
+ { kind: "quality" },
846
+ { kind: "toggle", key: "vectorContours" },
847
+ { kind: "field", key: "contourWidthPx" },
848
+ { kind: "field", key: "minorContourWidthPx" },
849
+ { kind: "color", key: "majorContourColor" },
850
+ { kind: "color", key: "minorContourColor" },
851
+ { kind: "toggle", key: "fullResolution" },
852
+ { kind: "toggle", key: "msaa" },
853
+ { kind: "field", key: "fieldCells" }
854
+ ];
855
+ var fieldByKey = new Map(FIELDS.map((field) => [field.key, field]));
856
+ var toggleByKey = new Map(TOGGLES.map((toggle) => [toggle.key, toggle]));
857
+ var colorByKey = new Map(COLOR_FIELDS.map((field) => [field.key, field]));
858
+ var graphicsFieldKeys = new Set(
859
+ GRAPHICS.flatMap((item) => item.kind === "field" ? [item.key] : [])
860
+ );
771
861
  var unitSymbol = () => depthUnit === "foot" ? "ft" : "m";
772
862
  var toDisplay = (metres) => depthUnit === "foot" ? metres / METRES_PER_FOOT : metres;
773
863
  var fromDisplay = (value) => depthUnit === "foot" ? value * METRES_PER_FOOT : value;
@@ -835,6 +925,28 @@ function numberField(field) {
835
925
  }
836
926
  return wrap2;
837
927
  }
928
+ function toggleField(toggle) {
929
+ const wrap2 = document.createElement("label");
930
+ wrap2.className = "field row";
931
+ const name = document.createElement("span");
932
+ name.className = "name";
933
+ name.textContent = toggle.label;
934
+ const input = document.createElement("input");
935
+ input.type = "checkbox";
936
+ input.checked = Boolean(settings[toggle.key]);
937
+ input.addEventListener("change", () => {
938
+ settings[toggle.key] = input.checked;
939
+ void save();
940
+ });
941
+ wrap2.append(name, input);
942
+ if (toggle.hint) {
943
+ const hint = document.createElement("span");
944
+ hint.className = "hint";
945
+ hint.textContent = toggle.hint;
946
+ wrap2.appendChild(hint);
947
+ }
948
+ return wrap2;
949
+ }
838
950
  function build() {
839
951
  root.replaceChildren();
840
952
  historyRows.length = 0;
@@ -883,6 +995,57 @@ function build() {
883
995
  sourceHint.textContent = "History draws the vessel's own recorded track; tiles draw the server-built bathymetry store, extended live.";
884
996
  source.appendChild(sourceHint);
885
997
  root.appendChild(source);
998
+ for (const field of FIELDS) {
999
+ if (!graphicsFieldKeys.has(field.key)) {
1000
+ root.appendChild(numberField(field));
1001
+ }
1002
+ }
1003
+ const graphicsHeading = document.createElement("h3");
1004
+ graphicsHeading.textContent = "Graphics Settings";
1005
+ root.appendChild(graphicsHeading);
1006
+ for (const item of GRAPHICS) {
1007
+ if (item.kind === "quality") {
1008
+ root.appendChild(qualityField());
1009
+ } else if (item.kind === "toggle") {
1010
+ const toggle = toggleByKey.get(item.key);
1011
+ if (toggle) {
1012
+ root.appendChild(toggleField(toggle));
1013
+ }
1014
+ } else if (item.kind === "color") {
1015
+ const color = colorByKey.get(item.key);
1016
+ if (color) {
1017
+ root.appendChild(colorField(color));
1018
+ }
1019
+ } else {
1020
+ const field = fieldByKey.get(item.key);
1021
+ if (field) {
1022
+ root.appendChild(numberField(field));
1023
+ }
1024
+ }
1025
+ }
1026
+ syncHistoryDisabled();
1027
+ }
1028
+ function colorField(field) {
1029
+ const wrap2 = document.createElement("label");
1030
+ wrap2.className = "field row";
1031
+ const name = document.createElement("span");
1032
+ name.className = "name";
1033
+ name.textContent = field.label;
1034
+ const input = document.createElement("input");
1035
+ input.type = "color";
1036
+ input.value = settings[field.key];
1037
+ input.addEventListener("input", () => {
1038
+ settings[field.key] = input.value;
1039
+ void save();
1040
+ });
1041
+ wrap2.append(name, input);
1042
+ const hint = document.createElement("span");
1043
+ hint.className = "hint";
1044
+ hint.textContent = field.hint;
1045
+ wrap2.appendChild(hint);
1046
+ return wrap2;
1047
+ }
1048
+ function qualityField() {
886
1049
  const quality = document.createElement("label");
887
1050
  quality.className = "field";
888
1051
  const qualityName = document.createElement("span");
@@ -910,11 +1073,7 @@ function build() {
910
1073
  qualityHint.className = "hint";
911
1074
  qualityHint.textContent = "Scales the shaded depth surface only; soundings, circles and labels always render at full resolution. Auto adapts to this GPU.";
912
1075
  quality.appendChild(qualityHint);
913
- root.appendChild(quality);
914
- for (const field of FIELDS) {
915
- root.appendChild(numberField(field));
916
- }
917
- syncHistoryDisabled();
1076
+ return quality;
918
1077
  }
919
1078
  async function save() {
920
1079
  await client.state.set(settings);