signalk-livedepth-plugin 0.2.1 → 0.3.2

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.
Files changed (86) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/README.md +67 -41
  3. package/dist/collector.d.ts +1 -1
  4. package/dist/collector.d.ts.map +1 -1
  5. package/dist/config.d.ts +52 -3
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +41 -4
  8. package/dist/config.js.map +1 -1
  9. package/dist/plotterext/manifest.d.ts +24 -0
  10. package/dist/plotterext/manifest.d.ts.map +1 -0
  11. package/dist/plotterext/manifest.js +79 -0
  12. package/dist/plotterext/manifest.js.map +1 -0
  13. package/dist/plotterext/provider.d.ts +7 -0
  14. package/dist/plotterext/provider.d.ts.map +1 -0
  15. package/dist/plotterext/provider.js +61 -0
  16. package/dist/plotterext/provider.js.map +1 -0
  17. package/dist/plugin.d.ts +15 -0
  18. package/dist/plugin.d.ts.map +1 -1
  19. package/dist/plugin.js +40 -8
  20. package/dist/plugin.js.map +1 -1
  21. package/dist/streams/live.d.ts +16 -4
  22. package/dist/streams/live.d.ts.map +1 -1
  23. package/dist/streams/live.js +164 -43
  24. package/dist/streams/live.js.map +1 -1
  25. package/dist/tiles/api.d.ts +21 -11
  26. package/dist/tiles/api.d.ts.map +1 -1
  27. package/dist/tiles/api.js +36 -27
  28. package/dist/tiles/api.js.map +1 -1
  29. package/dist/tiles/core/accumulator.d.ts +37 -0
  30. package/dist/tiles/core/accumulator.d.ts.map +1 -0
  31. package/dist/tiles/core/accumulator.js +75 -0
  32. package/dist/tiles/core/accumulator.js.map +1 -0
  33. package/dist/tiles/core/correction.d.ts +32 -0
  34. package/dist/tiles/core/correction.d.ts.map +1 -0
  35. package/dist/tiles/core/correction.js +43 -0
  36. package/dist/tiles/core/correction.js.map +1 -0
  37. package/dist/tiles/core/grid.d.ts +64 -0
  38. package/dist/tiles/core/grid.d.ts.map +1 -0
  39. package/dist/tiles/core/grid.js +127 -0
  40. package/dist/tiles/core/grid.js.map +1 -0
  41. package/dist/tiles/core/index.d.ts +7 -0
  42. package/dist/tiles/core/index.d.ts.map +1 -0
  43. package/dist/tiles/core/index.js +7 -0
  44. package/dist/tiles/core/index.js.map +1 -0
  45. package/dist/tiles/core/store.d.ts +37 -0
  46. package/dist/tiles/core/store.d.ts.map +1 -0
  47. package/dist/tiles/core/store.js +86 -0
  48. package/dist/tiles/core/store.js.map +1 -0
  49. package/dist/tiles/core/tile-source.d.ts +50 -0
  50. package/dist/tiles/core/tile-source.d.ts.map +1 -0
  51. package/dist/tiles/core/tile-source.js +86 -0
  52. package/dist/tiles/core/tile-source.js.map +1 -0
  53. package/dist/tiles/core/types.d.ts +11 -0
  54. package/dist/tiles/core/types.d.ts.map +1 -0
  55. package/dist/tiles/core/types.js +2 -0
  56. package/dist/tiles/core/types.js.map +1 -0
  57. package/dist/tiles/index.d.ts +1 -1
  58. package/dist/tiles/index.d.ts.map +1 -1
  59. package/dist/tiles/index.js +1 -1
  60. package/dist/tiles/index.js.map +1 -1
  61. package/dist/tiles/seed.d.ts +1 -1
  62. package/dist/tiles/seed.d.ts.map +1 -1
  63. package/dist/tiles/seed.js +1 -1
  64. package/dist/tiles/seed.js.map +1 -1
  65. package/dist/tiles/store.d.ts +1 -1
  66. package/dist/tiles/store.d.ts.map +1 -1
  67. package/dist/tiles/store.js +1 -1
  68. package/dist/tiles/store.js.map +1 -1
  69. package/dist/tiles/writer.d.ts +1 -1
  70. package/dist/tiles/writer.d.ts.map +1 -1
  71. package/dist/tiles/writer.js +1 -1
  72. package/dist/tiles/writer.js.map +1 -1
  73. package/dist/tsconfig.tsbuildinfo +1 -1
  74. package/dist/types.d.ts +3 -0
  75. package/dist/types.d.ts.map +1 -1
  76. package/package.json +27 -6
  77. package/public/config.html +14 -0
  78. package/public/index.html +15 -0
  79. package/public/js/config.js +939 -0
  80. package/public/js/config.js.map +7 -0
  81. package/public/js/render-worker.js +866 -0
  82. package/public/js/render-worker.js.map +7 -0
  83. package/public/js/renderer.js +1159 -0
  84. package/public/js/renderer.js.map +7 -0
  85. package/public/renderer.html +14 -0
  86. package/public/styles.css +110 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,113 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here, newest first. The
4
+ format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
5
+ versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.3.2] - 2026-10-19
8
+
9
+ ### Added
10
+
11
+ - Depth from **other vessels**. The plugin now records any vessel on the server
12
+ that publishes a depth on the selected datum, so a tender or a second
13
+ sounder-equipped vessel (for example a dinghy) is folded into the bathymetry
14
+ automatically. AIS targets — which have a position but no depth — are ignored.
15
+ The transducer correction describes this vessel's hull, so it is applied to
16
+ this vessel's soundings only. `vessels.include` / `vessels.exclude` narrow the
17
+ set if needed.
18
+ - A **Render quality** setting: Auto, or High / Balanced / Low. It scales only
19
+ the shaded depth surface; soundings, circles and labels always render at full
20
+ resolution. Auto adapts the surface to the GPU, and a frame-rate readout is
21
+ logged to the console.
22
+ - A temporary `debug.vesselFootprint` option draws the vessel's LOA × beam on
23
+ the chart layer, for checking where a sounding lands relative to the hull.
24
+
25
+ ### Fixed
26
+
27
+ - A transducer forward of midships is placed ahead of the reference, not behind
28
+ it. The offset sign was inverted, which drew every sounding astern.
29
+ - The chart layer accepts the host's object-shaped `navigation.position`
30
+ (`{ latitude, longitude }`), so live soundings are no longer silently dropped.
31
+ - Panning or zooming re-fetches the tiles for the new view; previously the layer
32
+ kept drawing the previous view's tile set.
33
+ - A vessel that goes quiet keeps its subscription, so the deltas it replays on
34
+ reconnect are recorded rather than lost. A GPS-only vessel with no compass
35
+ falls back to course over ground for its heading.
36
+
37
+ ### Changed
38
+
39
+ - The chart layer renders at the display's pixel ratio instead of oversampling
40
+ at 2×, caches the per-frame cluster aggregation, and patches the depth field
41
+ incrementally on a live flush instead of rebuilding the grid. This cuts the
42
+ browser's CPU/GPU cost substantially, especially on a lower-powered GPU.
43
+
44
+ ## [0.3.1] - 2026-10-16
45
+
46
+ ### Fixed
47
+
48
+ - The chart layer no longer lags the vessel by 2–3 seconds. Live soundings were
49
+ batched for two seconds, and each batch re-fetched every tile for the view
50
+ over HTTP; they now fold into the frame every 300 ms without a network round
51
+ trip, so the surface fills in under the bow.
52
+
53
+ ## [0.3.0] - 2026-10-15
54
+
55
+ The LiveDepth chart layer, and the merge that brings everything into one
56
+ package. The chart layer needs a host that implements `overlays.image` —
57
+ Freeboard-SK **3.4.0-beta.0 or later**.
58
+
59
+ ### Added
60
+
61
+ - The **LiveDepth chart layer**: an image map overlay offered to
62
+ plotter-extensions chartplotters (Freeboard-SK 3.4.0-beta.0 or later), drawn
63
+ by a headless background runtime that shades the depth surface, draws isobaths
64
+ and
65
+ labels the shoals. It appears in the chartplotter's Chart list with show/hide
66
+ and opacity controls, and its settings open from the layer's row or the
67
+ LiveDepth toolbar button.
68
+
69
+ ### Changed
70
+
71
+ - The shared tile algorithm (`signalk-livedepth-tiles`) is folded into this
72
+ package under `src/tiles/core/`; that published package is no longer a
73
+ dependency.
74
+ - Bathymetry data is served from the extension's own top-level path
75
+ (`/plotterext/signalk-livedepth-plugin/bathymetry/…`) so a read-only user's
76
+ chartplotter can reach it; the one-time history rebuild stays an admin route.
77
+
78
+ ### Fixed
79
+
80
+ - The config schema no longer emits a `default: undefined`, which the server
81
+ dropped when storing the schema as JSON.
82
+ - Switching the depth source now takes effect: the live Signal K subscription
83
+ starts and stops with the source.
84
+ - The settings panel greys the history-only fields while the depth source is the
85
+ plugin's tiles, and shows depth values in the user's preferred unit.
86
+
87
+ ## [0.2.1] - 2026-10-14
88
+
89
+ ### Fixed
90
+
91
+ - Serve tiles as raw bytes, not JSON — express was JSON-encoding the `Uint8Array`
92
+ `encodeTile` returns, so a client decoded the JSON text as sparse records.
93
+ - Read the vessel length overall from `design.length`, so transducer correction
94
+ no longer reports it missing on servers that have it.
95
+
96
+ ## [0.2.0] - 2026-10-14
97
+
98
+ ### Added
99
+
100
+ - Transducer position correction.
101
+
102
+ ### Changed
103
+
104
+ - Trimmed the configuration to the depth path, the transducer's position, the
105
+ correction mode and the one-time history rebuild.
106
+
107
+ ## [0.1.0] - 2026-10-13
108
+
109
+ ### Added
110
+
111
+ - First release: build a gridded bathymetry tile store from the vessel's own
112
+ position and depth, serve it to a chart client, and seed it from the server's
113
+ History API.
package/README.md CHANGED
@@ -1,54 +1,80 @@
1
- # signalk-livedepth-plugin
1
+ # LiveDepth
2
2
 
3
- A Signal K server plugin that builds a **gridded bathymetry tile store** from the
4
- vessel's own position and depth, and serves it to a chart client's LiveDepth
5
- layer. It is the server side of Freeboard-SK's LiveDepth layer.
3
+ **LiveDepth builds and visualises a depth map from your own soundings, in real
4
+ time, as your vessel moves.** Everywhere you go, your depth sounder's readings
5
+ are turned into bathymetric data you can see on the chart — so the ground you've
6
+ already covered is there to look at the next time you're in the area.
6
7
 
7
8
  ## What it does
8
9
 
9
- - Subscribes to the vessel's own `environment.depth.*` and `navigation.position`,
10
- and folds each sounding into a Web-Mercator XYZ tile store: 256-cell tiles,
11
- base level `z20` (≈0.15 m per cell), min-pooled down to `z4` (≈2.4 km per
12
- cell). A tile is stored sparsely — only the cells a sounding fell in — as a
13
- 5-byte record (`cx, cy, depthCm, count`) keeping the shallowest depth, so
14
- zooming out never deepens a shoal. The tile algorithm itself lives in
15
- [`signalk-livedepth-tiles`](https://www.npmjs.com/package/signalk-livedepth-tiles),
16
- shared with the chart client so both build identical tiles.
17
- - Serves the tiles over HTTP so a chart client can draw a depth surface for the
18
- area without replaying the raw track or interpolating at query time.
19
- - Can seed the store from the server's History API at the finest granularity it
20
- offers — a one-time, resumable rebuild for a store that already has a track.
21
-
22
- ## Routes
23
-
24
- Mounted by the server at `/plugins/signalk-livedepth-plugin`:
25
-
26
- | Route | Returns |
27
- | -------------------------------- | -------------------------------------------------------------------------------------- |
28
- | `GET /bathymetry/meta` | grid spec (base/min zoom, tile size, record size) and the depth path/offsets to mirror |
29
- | `GET /bathymetry/tiles/:z/:x/:y` | the sparse tile blob (`application/octet-stream`), or `404` |
30
- | `GET /bathymetry/seed` | admin only: status of the one-time history rebuild |
31
- | `POST /bathymetry/seed` | admin only: start the one-time history rebuild (`202`) |
32
-
33
- A client seeds its view from the tiles, then keeps its own copy current from the
34
- same Signal K stream.
35
-
36
- ## Configuration
37
-
38
- - **Path** — the `environment.depth.*` path to record.
39
- - **Depth Sounder / GPS Receiver** — the sensor offsets, and the source to pin
40
- each path to (so soundings from a second GPS don't smear the track).
41
- - **Rebuild from History** — a one-shot rebuild from the server's History API;
42
- it fires once when saved and clears itself when it finishes.
10
+ - **Records as you go.** Each depth reading is placed where your vessel was when
11
+ it was taken, building a picture of the seabed along your track. No surveying
12
+ needed — just your normal boating.
13
+ - **Draws it on the chart.** A compatible chartplotter (Freeboard-SK) shows the
14
+ depth as a shaded surface with depth-contour lines, so you can see the shape of
15
+ the ground and where it shallows.
16
+ - **Never hides a shoal.** Where readings overlap, the shallowest one wins, so
17
+ zooming out can't bury a shallow patch under the deeper water around it.
18
+ - **Live or accumulated.** Show your own recent track, or the depth map the
19
+ server has built up over time — extended live as you move.
20
+ - **Rebuild from history.** Already have a track recorded on the server? A
21
+ one-time rebuild fills the map in from it.
22
+
23
+ ## What you need
24
+
25
+ - A Signal K server with your depth sounder and GPS feeding it.
26
+ - A chartplotter that supports plotter extensions — **Freeboard-SK
27
+ 3.4.0-beta.0 or later**, or another host that supports the `overlays.image`
28
+ capability.
29
+ - The plugin enabled on the server (install it from the App Store, then switch it
30
+ on in the server's plugin settings).
31
+
32
+ ## Using it
33
+
34
+ Once enabled, **Live depth** appears in the chartplotter's Chart list, under
35
+ _Plugin layers_, with its own show/hide and opacity controls — saved just like a
36
+ chart's. Open **Layer settings** on its row (or the LiveDepth toolbar button) to
37
+ choose what it shows:
38
+
39
+ - **Show the layer** — on or off.
40
+ - **Depth source** — your own recent track, or the accumulated depth map.
41
+ - **Shade limit** — the depth the shading runs to; deeper water is left to the
42
+ chart.
43
+ - **Isobath interval** — how far apart the depth-contour lines are.
44
+ - **Grid cell**, **Merge band** — how readings are grouped into the dots on the
45
+ chart.
46
+ - **Max depth**, **Safety depth** — which readings are drawn, and which shallow
47
+ ones are marked individually.
48
+
49
+ Depth values are shown in your preferred units.
50
+
51
+ ## Server settings
52
+
53
+ - **Path** — which depth measurement to record (below surface, transducer or
54
+ keel).
55
+ - **Depth transducer** — where the sounder sits on the hull, so each reading is
56
+ placed at it rather than at the position the server reports.
57
+ - **Transducer position correction** — shift readings from the vessel's
58
+ reference point to the transducer (needs the server's own GNSS correction on).
59
+ - **Rebuild from history** — a one-time rebuild of the depth map from the track
60
+ the server already has.
61
+
62
+ ## How it works
63
+
64
+ The plugin runs on your Signal K server and turns each sounding into a
65
+ Web-Mercator depth map, keeping the shallowest reading for every spot. A
66
+ chartplotter that supports plotter extensions draws it as a map layer, rendering
67
+ in the browser. The plugin offers the layer to the chartplotter automatically —
68
+ there's nothing to configure on the chart side.
43
69
 
44
70
  ## Development
45
71
 
46
72
  ```bash
47
73
  npm install
48
- npm run build # tsc -b -> dist/
49
- npm test # vitest
74
+ npm run build # server code (dist/) + the chart-layer pages (public/)
75
+ npm test # vitest
50
76
  npm run format
51
77
  npm run lint
52
78
  ```
53
79
 
54
- Node `>=22.5` (the store uses the built-in `node:sqlite`).
80
+ Node `>=22.5`.
@@ -1,6 +1,6 @@
1
1
  import { Writable } from "stream";
2
2
  import { ServerAPI } from "@signalk/server-api";
3
- import { TransducerOffset } from "signalk-livedepth-tiles";
3
+ import { TransducerOffset } from "./tiles/core/index.js";
4
4
  import { Config } from "./config.js";
5
5
  export interface CollectorOptions {
6
6
  app: ServerAPI;
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,EAAE,QAAQ,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,0CAkBlB"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,EAAE,QAAQ,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,0CAkBlB"}
package/dist/config.d.ts CHANGED
@@ -13,10 +13,23 @@ export type Config = {
13
13
  /** Shift soundings from the vessel reference point the server reports to the
14
14
  * transducer. `off` leaves them where the server put them. */
15
15
  transducerCorrection: "off" | "replace";
16
+ /** Which vessels to record soundings from. By default every vessel that
17
+ * publishes a depth on the selected datum is recorded — a tender or a second
18
+ * sounder-equipped vessel is picked up automatically, while AIS targets
19
+ * (position but no depth) are ignored. `include`/`exclude` narrow that set. */
20
+ vessels?: {
21
+ include?: string[];
22
+ exclude?: string[];
23
+ };
16
24
  seed?: {
17
25
  run?: boolean;
18
26
  resolution?: number;
19
27
  };
28
+ /** Temporary diagnostics, removed once the geometry is verified. */
29
+ debug?: {
30
+ /** Draw the vessel's footprint (LOA × beam) in the chart layer. */
31
+ vesselFootprint?: boolean;
32
+ };
20
33
  };
21
34
  export declare const DepthPaths: readonly ["belowSurface", "belowTransducer", "belowKeel"];
22
35
  export declare function schema(app: ServerAPI): {
@@ -29,7 +42,7 @@ export declare function schema(app: ServerAPI): {
29
42
  description: string;
30
43
  enum: readonly ["belowSurface", "belowTransducer", "belowKeel"];
31
44
  enumNames: string[];
32
- default: "belowKeel" | "belowSurface" | "belowTransducer" | undefined;
45
+ default?: "belowKeel" | "belowSurface" | "belowTransducer" | undefined;
33
46
  };
34
47
  sounder: {
35
48
  type: string;
@@ -41,13 +54,13 @@ export declare function schema(app: ServerAPI): {
41
54
  type: string;
42
55
  title: string;
43
56
  minimum: number;
44
- default: unknown;
57
+ default?: {} | null | undefined;
45
58
  };
46
59
  x: {
47
60
  type: string;
48
61
  title: string;
49
62
  description: string;
50
- default: unknown;
63
+ default?: {} | null | undefined;
51
64
  };
52
65
  };
53
66
  };
@@ -59,6 +72,29 @@ export declare function schema(app: ServerAPI): {
59
72
  enumNames: string[];
60
73
  default: string;
61
74
  };
75
+ vessels: {
76
+ type: string;
77
+ title: string;
78
+ description: string;
79
+ properties: {
80
+ include: {
81
+ type: string;
82
+ title: string;
83
+ description: string;
84
+ items: {
85
+ type: string;
86
+ };
87
+ };
88
+ exclude: {
89
+ type: string;
90
+ title: string;
91
+ description: string;
92
+ items: {
93
+ type: string;
94
+ };
95
+ };
96
+ };
97
+ };
62
98
  seed: {
63
99
  type: string;
64
100
  title: string;
@@ -78,6 +114,19 @@ export declare function schema(app: ServerAPI): {
78
114
  };
79
115
  };
80
116
  };
117
+ debug: {
118
+ type: string;
119
+ title: string;
120
+ description: string;
121
+ properties: {
122
+ vesselFootprint: {
123
+ type: string;
124
+ default: boolean;
125
+ title: string;
126
+ description: string;
127
+ };
128
+ };
129
+ };
81
130
  };
82
131
  };
83
132
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,MAAM,MAAM,GAAG;IACnB;0DACsD;IACtD,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC;;oEAEgE;IAChE,OAAO,EAAE;QACP,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF;kEAC8D;IAC9D,oBAAoB,EAAE,KAAK,GAAG,SAAS,CAAC;IACxC,IAAI,CAAC,EAAE;QACL,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,UAAU,YACrB,cAAc,EACd,iBAAiB,EACjB,WAAW,CACH,CAAC;AAEX,wBAAgB,MAAM,CAAC,GAAG,EAAE,SAAS;IAKjC,IAAI;IACJ,WAAW;IAEX,UAAU;QACR,IAAI;YACF,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,IAAI;YACJ,SAAS;YAKT,OAAO;;QAET,OAAO;YACL,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,QAAQ;YACR,UAAU;gBACR,CAAC;oBACC,IAAI;oBACJ,KAAK;oBACL,OAAO;oBACP,OAAO;;gBAET,CAAC;oBACC,IAAI;oBACJ,KAAK;oBACL,WAAW;oBACX,OAAO;;;;QAIb,oBAAoB;YAClB,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,IAAI;YACJ,SAAS;YACT,OAAO;;QAET,IAAI;YACF,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,GAAG;oBACD,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;gBAGb,UAAU;oBACR,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;;;;EAOtB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,MAAM,MAAM,GAAG;IACnB;0DACsD;IACtD,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC;;oEAEgE;IAChE,OAAO,EAAE;QACP,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF;kEAC8D;IAC9D,oBAAoB,EAAE,KAAK,GAAG,SAAS,CAAC;IACxC;;;mFAG+E;IAC/E,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,IAAI,CAAC,EAAE;QACL,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,oEAAoE;IACpE,KAAK,CAAC,EAAE;QACN,mEAAmE;QACnE,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,UAAU,YACrB,cAAc,EACd,iBAAiB,EACjB,WAAW,CACH,CAAC;AAEX,wBAAgB,MAAM,CAAC,GAAG,EAAE,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAiD7B,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,IAAI;YACJ,SAAS;YACT,OAAO;;;YAGP,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,OAAO;oBACL,IAAI;oBACJ,KAAK;oBACL,WAAW;oBAEX,KAAK;wBAAI,IAAI;;;gBAEf,OAAO;oBACL,IAAI;oBACJ,KAAK;oBACL,WAAW;oBACX,KAAK;wBAAI,IAAI;;;;;;YAKjB,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,GAAG;oBACD,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;gBAGb,UAAU;oBACR,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;;;;YAMf,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,eAAe;oBACb,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;;;;EAOtB"}
package/dist/config.js CHANGED
@@ -5,9 +5,14 @@ export const DepthPaths = [
5
5
  ];
6
6
  export function schema(app) {
7
7
  const defaultPath = DepthPaths.find((path) => app.getSelfPath(`environment.depth.${path}.value`));
8
+ // A `default` is attached only when present: `default: undefined` survives in
9
+ // the object but is dropped when the server stores the schema as JSON, which
10
+ // its plugin schema check flags as data loss.
11
+ const fromBow = app.getSelfPath("sensors.depth.fromBow.value");
12
+ const fromCenter = app.getSelfPath("sensors.depth.fromCenter.value");
8
13
  return {
9
14
  type: "object",
10
- description: "Build a gridded bathymetry tile store from the vessel's own position and depth, and serve it to a chart client's LiveDepth layer.",
15
+ description: "Build a gridded bathymetry tile store from vessel soundings — your own and any other depth-equipped vessel on the server — and serve it to a chart client's LiveDepth layer.",
11
16
  properties: {
12
17
  path: {
13
18
  type: "string",
@@ -19,7 +24,7 @@ export function schema(app) {
19
24
  "Depth below transducer",
20
25
  "Depth below keel",
21
26
  ],
22
- default: defaultPath,
27
+ ...(defaultPath === undefined ? {} : { default: defaultPath }),
23
28
  },
24
29
  sounder: {
25
30
  type: "object",
@@ -31,13 +36,13 @@ export function schema(app) {
31
36
  type: "number",
32
37
  title: "Distance of the transducer from the bow (meters)",
33
38
  minimum: 0,
34
- default: app.getSelfPath("sensors.depth.fromBow.value"),
39
+ ...(fromBow === undefined ? {} : { default: fromBow }),
35
40
  },
36
41
  x: {
37
42
  type: "number",
38
43
  title: "Distance of the transducer from the center (meters)",
39
44
  description: "+ve to starboard, -ve to port",
40
- default: app.getSelfPath("sensors.depth.fromCenter.value"),
45
+ ...(fromCenter === undefined ? {} : { default: fromCenter }),
41
46
  },
42
47
  },
43
48
  },
@@ -49,6 +54,25 @@ export function schema(app) {
49
54
  enumNames: ["Off", "Replace with the transducer's position"],
50
55
  default: "off",
51
56
  },
57
+ vessels: {
58
+ type: "object",
59
+ title: "Vessels",
60
+ description: "Which vessel contexts to record. By default every vessel that publishes a depth on the selected datum is recorded — a tender or a second depth-equipped vessel is picked up automatically, while AIS targets (position but no depth) are ignored. Use these lists to narrow that set.",
61
+ properties: {
62
+ include: {
63
+ type: "array",
64
+ title: "Only these vessels",
65
+ description: "Record only these Signal K contexts, e.g. vessels.urn:mrn:signalk:uuid:…. Empty records every vessel that publishes a depth.",
66
+ items: { type: "string" },
67
+ },
68
+ exclude: {
69
+ type: "array",
70
+ title: "Never these vessels",
71
+ description: "Contexts to ignore even when they publish a depth.",
72
+ items: { type: "string" },
73
+ },
74
+ },
75
+ },
52
76
  seed: {
53
77
  type: "object",
54
78
  title: "Rebuild from History",
@@ -68,6 +92,19 @@ export function schema(app) {
68
92
  },
69
93
  },
70
94
  },
95
+ debug: {
96
+ type: "object",
97
+ title: "Debug",
98
+ description: "Temporary diagnostics, not for general use — they will be removed.",
99
+ properties: {
100
+ vesselFootprint: {
101
+ type: "boolean",
102
+ default: false,
103
+ title: "Draw the vessel footprint",
104
+ description: "Draw the vessel's footprint (design.length.overall × design.beam) on the chart layer, centred on navigation.position and rotated to the heading. Useful for checking where soundings land relative to the hull.",
105
+ },
106
+ },
107
+ },
71
108
  },
72
109
  };
73
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,cAAc;IACd,iBAAiB;IACjB,WAAW;CACH,CAAC;AAEX,MAAM,UAAU,MAAM,CAAC,GAAc;IACnC,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3C,GAAG,CAAC,WAAW,CAAC,qBAAqB,IAAI,QAAQ,CAAC,CACnD,CAAC;IACF,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EACT,mIAAmI;QACrI,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,OAAO;gBACd,WAAW,EACT,sIAAsI;gBACxI,IAAI,EAAE,UAAU;gBAChB,SAAS,EAAE;oBACT,qBAAqB;oBACrB,wBAAwB;oBACxB,kBAAkB;iBACnB;gBACD,OAAO,EAAE,WAAW;aACrB;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,kBAAkB;gBACzB,WAAW,EACT,sHAAsH;gBACxH,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;gBACpB,UAAU,EAAE;oBACV,CAAC,EAAE;wBACD,IAAI,EAAE,QAAQ;wBACd,KAAK,EAAE,kDAAkD;wBACzD,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,6BAA6B,CAAC;qBACxD;oBACD,CAAC,EAAE;wBACD,IAAI,EAAE,QAAQ;wBACd,KAAK,EAAE,qDAAqD;wBAC5D,WAAW,EAAE,+BAA+B;wBAC5C,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,gCAAgC,CAAC;qBAC3D;iBACF;aACF;YACD,oBAAoB,EAAE;gBACpB,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,gCAAgC;gBACvC,WAAW,EACT,2UAA2U;gBAC7U,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;gBACxB,SAAS,EAAE,CAAC,KAAK,EAAE,wCAAwC,CAAC;gBAC5D,OAAO,EAAE,KAAK;aACf;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,sBAAsB;gBAC7B,WAAW,EACT,iQAAiQ;gBACnQ,UAAU,EAAE;oBACV,GAAG,EAAE;wBACH,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,+CAA+C;wBACtD,WAAW,EACT,wGAAwG;qBAC3G;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,GAAG;wBACZ,KAAK,EAAE,8BAA8B;wBACrC,WAAW,EACT,kGAAkG;qBACrG;iBACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /** The providing plugin's id; also the plotterExtensions resource key. */
2
+ export declare const PLUGIN_ID = "signalk-livedepth-plugin";
3
+ /** Top-level, non-admin route the extension's pages and data are served from. */
4
+ export declare const ASSET_BASE = "/plotterext/signalk-livedepth-plugin";
5
+ /** The plotterExtensions manifest (see docs/api/plotter-extensions-api.md). */
6
+ export interface PlotterExtManifest {
7
+ name: string;
8
+ description: string;
9
+ version: string;
10
+ apiVersion: string;
11
+ requires: string[];
12
+ optional: string[];
13
+ buttons: unknown[];
14
+ panels: unknown[];
15
+ background: unknown[];
16
+ overlays: unknown[];
17
+ }
18
+ /** Build the extension manifest offered to a host chartplotter.
19
+ *
20
+ * One `image` overlay, drawn by a headless background runtime, placed above
21
+ * the charts and below the vessel/resources. A `mapToolbar` button opens the
22
+ * settings panel, which shares state with the runtime over the bus. */
23
+ export declare function buildManifest(version?: string): PlotterExtManifest;
24
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/plotterext/manifest.ts"],"names":[],"mappings":"AAIA,0EAA0E;AAC1E,eAAO,MAAM,SAAS,6BAA6B,CAAC;AACpD,iFAAiF;AACjF,eAAO,MAAM,UAAU,yCAA6B,CAAC;AAErD,+EAA+E;AAC/E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,UAAU,EAAE,OAAO,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAeD;;;;uEAIuE;AACvE,wBAAgB,aAAa,CAAC,OAAO,SAAkB,GAAG,kBAAkB,CAuD3E"}
@@ -0,0 +1,79 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /** The providing plugin's id; also the plotterExtensions resource key. */
5
+ export const PLUGIN_ID = "signalk-livedepth-plugin";
6
+ /** Top-level, non-admin route the extension's pages and data are served from. */
7
+ export const ASSET_BASE = `/plotterext/${PLUGIN_ID}`;
8
+ /** The plugin's own version, read from its package.json. */
9
+ function pluginVersion() {
10
+ try {
11
+ const here = dirname(fileURLToPath(import.meta.url));
12
+ const pkg = JSON.parse(readFileSync(join(here, "..", "..", "package.json"), "utf8"));
13
+ return pkg.version ?? "0.0.0";
14
+ }
15
+ catch {
16
+ return "0.0.0";
17
+ }
18
+ }
19
+ /** Build the extension manifest offered to a host chartplotter.
20
+ *
21
+ * One `image` overlay, drawn by a headless background runtime, placed above
22
+ * the charts and below the vessel/resources. A `mapToolbar` button opens the
23
+ * settings panel, which shares state with the runtime over the bus. */
24
+ export function buildManifest(version = pluginVersion()) {
25
+ return {
26
+ name: "LiveDepth",
27
+ description: "Draw your recorded depth as a live depth map on the chart, shaded with depth contours.",
28
+ version,
29
+ apiVersion: "1",
30
+ requires: ["background.iframe", "overlays.image", "signalk.stream"],
31
+ optional: ["buttons", "panels.iframe", "units", "map", "nightMode"],
32
+ buttons: [
33
+ {
34
+ id: "open-livedepth-settings",
35
+ title: "LiveDepth",
36
+ slot: "mapToolbar",
37
+ icon: "water",
38
+ action: { type: "togglePanel", panel: "livedepth-settings" },
39
+ },
40
+ ],
41
+ panels: [
42
+ {
43
+ id: "livedepth-settings",
44
+ title: "LiveDepth",
45
+ type: "iframe",
46
+ url: `${ASSET_BASE}/config.html`,
47
+ lifecycle: "keepAlive",
48
+ },
49
+ ],
50
+ background: [
51
+ {
52
+ id: "renderer",
53
+ type: "iframe",
54
+ url: `${ASSET_BASE}/renderer.html`,
55
+ },
56
+ ],
57
+ overlays: [
58
+ {
59
+ id: "depth",
60
+ title: "Live depth",
61
+ type: "image",
62
+ runtime: "renderer",
63
+ band: "aboveCharts",
64
+ visible: true,
65
+ opacity: 0.85,
66
+ minZoom: 4,
67
+ // The Chart list's "Layer settings" button opens this panel, so the
68
+ // layer's settings sit with the layer, not only behind the toolbar
69
+ // button.
70
+ configPanel: "livedepth-settings",
71
+ // No `preferredPixelRatio`: the host then uses the display's own device
72
+ // pixel ratio, which is native and sharp. Asking for 2 oversampled on a
73
+ // 1×/1.33× display, and that cost is paid per frame in the transfer and
74
+ // composite — the render-quality setting scales further if needed.
75
+ },
76
+ ],
77
+ };
78
+ }
79
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/plotterext/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,SAAS,GAAG,0BAA0B,CAAC;AACpD,iFAAiF;AACjF,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,SAAS,EAAE,CAAC;AAgBrD,4DAA4D;AAC5D,SAAS,aAAa;IACpB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CACrC,CAAC;QAC1B,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;uEAIuE;AACvE,MAAM,UAAU,aAAa,CAAC,OAAO,GAAG,aAAa,EAAE;IACrD,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,wFAAwF;QAC1F,OAAO;QACP,UAAU,EAAE,GAAG;QACf,QAAQ,EAAE,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,gBAAgB,CAAC;QACnE,QAAQ,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC;QACnE,OAAO,EAAE;YACP;gBACE,EAAE,EAAE,yBAAyB;gBAC7B,KAAK,EAAE,WAAW;gBAClB,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,oBAAoB,EAAE;aAC7D;SACF;QACD,MAAM,EAAE;YACN;gBACE,EAAE,EAAE,oBAAoB;gBACxB,KAAK,EAAE,WAAW;gBAClB,IAAI,EAAE,QAAQ;gBACd,GAAG,EAAE,GAAG,UAAU,cAAc;gBAChC,SAAS,EAAE,WAAW;aACvB;SACF;QACD,UAAU,EAAE;YACV;gBACE,EAAE,EAAE,UAAU;gBACd,IAAI,EAAE,QAAQ;gBACd,GAAG,EAAE,GAAG,UAAU,gBAAgB;aACnC;SACF;QACD,QAAQ,EAAE;YACR;gBACE,EAAE,EAAE,OAAO;gBACX,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,UAAU;gBACnB,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC;gBACV,oEAAoE;gBACpE,mEAAmE;gBACnE,UAAU;gBACV,WAAW,EAAE,oBAAoB;gBACjC,wEAAwE;gBACxE,wEAAwE;gBACxE,wEAAwE;gBACxE,mEAAmE;aACpE;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ServerAPI } from "@signalk/server-api";
2
+ /** Offer the plotter extension: register the read-only `plotterExtensions`
3
+ * resource and mount the extension's pages. Safe to call on every start — the
4
+ * provider is registered and the assets mounted once; `isRunning` reflects the
5
+ * plugin's current state so the extension leaves when the plugin is disabled. */
6
+ export declare function registerPlotterExtension(app: ServerAPI, isRunning: () => boolean): void;
7
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/plotterext/provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAYrD;;;iFAGiF;AACjF,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,SAAS,EACd,SAAS,EAAE,MAAM,OAAO,GACvB,IAAI,CAgCN"}