@jax-data-science/sci-image-visualizer 0.9.0 → 0.10.0
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/esm2022/index.mjs +7 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +1 -1
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
- package/esm2022/lib/models/class-preset.mjs +1 -1
- package/esm2022/lib/models/polygon-factory.mjs +17 -1
- package/esm2022/lib/models/region-geojson.mjs +44 -6
- package/esm2022/lib/models/region.mjs +1 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
- package/esm2022/lib/region-editor/region-editor.component.mjs +527 -42
- package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
- package/esm2022/lib/region-editor/region-persistence.service.mjs +36 -10
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
- package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
- package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/routing-visualizer.service.mjs +418 -22
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/store/class-color.util.mjs +10 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-scope-cache.mjs +5 -1
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +724 -12
- package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
- package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
- package/esm2022/lib/visualizer/region-load.mjs +67 -4
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +128 -6
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs} +7239 -1153
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs} +4 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
- package/fesm2022/region-source.worker.js +1067 -0
- package/index.d.ts +6 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/region-editor-api.contract.d.ts +84 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/visualizer.contract.d.ts +10 -0
- package/lib/contracts/viz-config.d.ts +8 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
- package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
- package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
- package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
- package/lib/models/class-preset.d.ts +7 -0
- package/lib/models/polygon-factory.d.ts +5 -0
- package/lib/models/region-geojson.d.ts +40 -0
- package/lib/models/region.d.ts +19 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
- package/lib/region-editor/region-editor.component.d.ts +133 -17
- package/lib/region-editor/region-metrics.d.ts +8 -0
- package/lib/region-editor/region-persistence.service.d.ts +12 -4
- package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
- package/lib/region-overlay/region-geometry.d.ts +4 -3
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/routing-visualizer.service.d.ts +138 -1
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/store/class-color.util.d.ts +6 -3
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-scope-cache.d.ts +2 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +206 -2
- package/lib/store/visualizer-store.service.d.ts +10 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
- package/lib/toolbar/toolbar.component.d.ts +9 -2
- package/lib/visualizer/region-load.d.ts +23 -4
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +31 -0
- package/package.json +2 -2
- package/src/lib/assets/slice.svg +23 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
|
@@ -5,20 +5,12 @@ import { ConfirmationService, MessageService } from 'primeng/api';
|
|
|
5
5
|
import { IRegionEditorApi } from '../contracts/region-editor-api.contract';
|
|
6
6
|
import { RegionPersistenceService } from './region-persistence.service';
|
|
7
7
|
import { ClassColorEdit } from './region-color-dialog/region-color-dialog.component';
|
|
8
|
+
import { ClassTreePick } from './class-tree/class-tree.component';
|
|
9
|
+
import type { RegionSourceView } from '../region-source/region-source';
|
|
10
|
+
import type { RegionClassNode } from '../region-source/region-tiles';
|
|
8
11
|
import { MaskExportService, MaskMode } from './mask-export.service';
|
|
9
12
|
import { PixelSize } from './region-metrics';
|
|
10
13
|
import * as i0 from "@angular/core";
|
|
11
|
-
/**
|
|
12
|
-
* The Region Editor (`<region-editor>`): the table of the active image's
|
|
13
|
-
* annotation regions with class presets, colours, labels, GeoJSON import /
|
|
14
|
-
* export / server save and mask export. Self-contained: it talks to the viewer
|
|
15
|
-
* only through {@link REGION_EDITOR_API} (and the host's REGION_IO_PORT), so it
|
|
16
|
-
* has no inputs or outputs.
|
|
17
|
-
*
|
|
18
|
-
* OnPush: template events re-render it; state that lands asynchronously (the
|
|
19
|
-
* API's region / selection / preset / image-meta streams, save and mask-export
|
|
20
|
-
* progress, file reads) marks it for check.
|
|
21
|
-
*/
|
|
22
14
|
export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
23
15
|
private regionApi;
|
|
24
16
|
private messageService;
|
|
@@ -26,6 +18,14 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
26
18
|
private persistence;
|
|
27
19
|
private maskExport;
|
|
28
20
|
private overlayPanel;
|
|
21
|
+
/**
|
|
22
|
+
* Whether the editor is on screen (its dialog open). Closed, it asks the region source nothing:
|
|
23
|
+
* its page of features, its class counts and, in a volume view, its classes' volumes are each a
|
|
24
|
+
* request over the whole set (a stack's every slice), and they competed with the volume's own
|
|
25
|
+
* slice loading for nothing anyone could see. Opened, it reads them again.
|
|
26
|
+
*/
|
|
27
|
+
set active(value: boolean);
|
|
28
|
+
private isActive;
|
|
29
29
|
protected regions: Region[];
|
|
30
30
|
protected selectedRegions: Region[];
|
|
31
31
|
protected showShapeLabel: boolean;
|
|
@@ -62,6 +62,56 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
62
62
|
* avoids needing a unique id field. */
|
|
63
63
|
protected editingLabelRegions: Map<Region, string>;
|
|
64
64
|
protected showSaveAsDialog: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* The slice's region source (a large region set drawn by level of detail), or null. Its
|
|
67
|
+
* features are rows of the table after the regions — stand-ins until one is selected or edited,
|
|
68
|
+
* which takes it into the regions — and its classes count in the classes panel.
|
|
69
|
+
*/
|
|
70
|
+
protected sourceView: RegionSourceView | null;
|
|
71
|
+
/** Features still in the source (the table's rows after the regions). */
|
|
72
|
+
private sourceTotal;
|
|
73
|
+
/** Stand-in rows for the source features on the current page. */
|
|
74
|
+
private sourceRows;
|
|
75
|
+
/** Features per class still in the source. */
|
|
76
|
+
private sourceClassCounts;
|
|
77
|
+
/** The stand-in rows (rows of a source feature, not of a region). */
|
|
78
|
+
private readonly standIns;
|
|
79
|
+
private standInSeq;
|
|
80
|
+
/** Bumped per source refresh, so a late answer is dropped. */
|
|
81
|
+
private sourceRequest;
|
|
82
|
+
/** The classes the table's Class column offers: the presets and the region source's classes
|
|
83
|
+
* (a dropdown can only show a value that is one of its options). */
|
|
84
|
+
protected tablePresetSet: PresetSet;
|
|
85
|
+
/** Whether regions are drawn filled (the atlas look) rather than outlined. */
|
|
86
|
+
protected regionsFilled: boolean;
|
|
87
|
+
/** Whether a volume view is on screen (classes can then be shown in 3D). */
|
|
88
|
+
protected volumeView: boolean;
|
|
89
|
+
/** Whether the volume view's slice pane is wanted (one slice edited beside the 3D view). */
|
|
90
|
+
private slicePane;
|
|
91
|
+
/** Whether the volume view draws the regions through the volume (see toggleThroughVolume). */
|
|
92
|
+
protected regionsThroughVolume: boolean;
|
|
93
|
+
/** Classes shown in 3D in the volume view, each with the classes its surface covers. */
|
|
94
|
+
protected shown3d: Map<string, string[]>;
|
|
95
|
+
/** The classes of the class tree's pick (it and its subtree), as long as the pick holds. */
|
|
96
|
+
private pickedClasses;
|
|
97
|
+
/** The selected rows' classes, marked in the class lists. */
|
|
98
|
+
protected markedClasses: ReadonlySet<string>;
|
|
99
|
+
/** The surfaces highlighted in the volume view (their keys, joined). */
|
|
100
|
+
private highlighted3d;
|
|
101
|
+
/** The colour each shown surface was last drawn in. */
|
|
102
|
+
private colors3d;
|
|
103
|
+
/** Their names, for the class lists' toggles (a new set per change, for OnPush). */
|
|
104
|
+
protected shown3dNames: ReadonlySet<string>;
|
|
105
|
+
/** The classes hidden from view (their regions, source features and surfaces). */
|
|
106
|
+
protected hiddenClasses: ReadonlySet<string>;
|
|
107
|
+
/** Whether a region set's class hierarchy is shown as a tree (rather than the class list). */
|
|
108
|
+
protected classTreeView: boolean;
|
|
109
|
+
/** The class picked last in the class tree. */
|
|
110
|
+
protected pickedClass: string | null;
|
|
111
|
+
/** Regions per class (the regions' and the source's), for the class tree. */
|
|
112
|
+
protected treeCounts: Map<string, number>;
|
|
113
|
+
/** A class's colour, for the class tree: a new function per colour change, so the tree repaints. */
|
|
114
|
+
protected treeColor: (name: string) => string;
|
|
65
115
|
protected saveAsFilename: string;
|
|
66
116
|
protected saveAsFileExists: boolean;
|
|
67
117
|
/** True while a GeoJSON persist is serializing/uploading — drives the dialog's
|
|
@@ -115,6 +165,52 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
115
165
|
* intensity-profile lines the editor never sees).
|
|
116
166
|
*/
|
|
117
167
|
protected onSelectionChanged(): void;
|
|
168
|
+
/** Whether the slice has a region source: it then has regions to save even with an empty table. */
|
|
169
|
+
protected get hasRegionSource(): boolean;
|
|
170
|
+
/** Rows in the table: the regions, then the features still in the region source. */
|
|
171
|
+
protected get tableTotal(): number;
|
|
172
|
+
/** The class hierarchy of the slice's region source, when it has one (the classes as a tree). */
|
|
173
|
+
protected get classHierarchy(): RegionClassNode[] | null;
|
|
174
|
+
/** Whether `row` is a region-source feature's stand-in rather than a region. */
|
|
175
|
+
protected isSourceRow(row: Region): boolean;
|
|
176
|
+
private sourceIds;
|
|
177
|
+
/** A table row for a source feature: no geometry until it is taken. */
|
|
178
|
+
private standIn;
|
|
179
|
+
/**
|
|
180
|
+
* Re-read the source part of the table (the stand-ins on the current page, the count) and the
|
|
181
|
+
* source's class counts. The page holds regions first, so its source rows start at
|
|
182
|
+
* `max(first, regions)` − regions.
|
|
183
|
+
*/
|
|
184
|
+
private refreshSource;
|
|
185
|
+
/** Take a source row's feature into the regions, then run `then` on the region it became. */
|
|
186
|
+
private takeThen;
|
|
187
|
+
/** Toggle the filled (atlas) look: each region filled in its colour, labels inside. */
|
|
188
|
+
/** In a volume view: the regions drawn through the volume, or hidden behind what it shows. */
|
|
189
|
+
protected toggleThroughVolume(): void;
|
|
190
|
+
protected toggleFill(): void;
|
|
191
|
+
/**
|
|
192
|
+
* Show or hide a class in the volume view as a 3D reconstruction — a tree node with every class
|
|
193
|
+
* under it, as one surface in its colour.
|
|
194
|
+
*/
|
|
195
|
+
protected toggleClass3d(name: string, classes?: string[]): void;
|
|
196
|
+
/** Hide (or show again) these classes' regions, wherever they are drawn. */
|
|
197
|
+
protected setClassesHidden(classes: readonly string[], hidden: boolean): void;
|
|
198
|
+
/** The surfaces shown in 3D, in their classes' colours now. */
|
|
199
|
+
private groups3d;
|
|
200
|
+
/** The classes selected now: the class tree's pick (with its subtree) and the selected rows'. */
|
|
201
|
+
private selectedClassNames;
|
|
202
|
+
/**
|
|
203
|
+
* Highlight, in the volume view, the surfaces holding a selected class (focus + context: they
|
|
204
|
+
* turn near opaque, the others fade), and mark the selected rows' classes in the class lists.
|
|
205
|
+
*/
|
|
206
|
+
private updateSelectionHighlight;
|
|
207
|
+
/** A surface clicked in the volume view: pick its class as the tree would; beside them, clear. */
|
|
208
|
+
private onPicked3d;
|
|
209
|
+
/** A class colour changed (its swatch, or Manage): repaint the surfaces shown in 3D whose colour it changed. */
|
|
210
|
+
private recolor3d;
|
|
211
|
+
private show3d;
|
|
212
|
+
/** Pick a class in the class tree: select its regions and its subclasses', the source's taken. */
|
|
213
|
+
protected pickClasses(pick: ClassTreePick): Promise<void>;
|
|
118
214
|
/**
|
|
119
215
|
* Rows for regions coming from the visualizer: neutral `Region`s with bounds,
|
|
120
216
|
* colour and label already populated. A region without a colour is shown with
|
|
@@ -154,16 +250,26 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
154
250
|
/** The current page of the table. Memoized on (regions, first, rows), so
|
|
155
251
|
* change detection doesn't hand p-table a new array every tick (RT-20). */
|
|
156
252
|
protected get pagedRegions(): Region[];
|
|
253
|
+
/** In a volume view, each class's volume over the whole stack, for the table (null: areas). */
|
|
254
|
+
protected tableVolumes: ReadonlyMap<string, number | null> | null;
|
|
255
|
+
/** Bumped when the regions change, so a volume computed before is dropped. */
|
|
256
|
+
private volumeRequest;
|
|
257
|
+
/** Compute the volumes of the classes on the table's page that are not known yet. */
|
|
258
|
+
private requestVolumes;
|
|
259
|
+
/** The regions changed (or the view did): forget the volumes and compute the page's again. */
|
|
260
|
+
private resetVolumes;
|
|
157
261
|
private _pageKey;
|
|
158
262
|
private _page;
|
|
159
263
|
protected onPageChange(event: {
|
|
160
264
|
first?: number;
|
|
161
265
|
rows?: number;
|
|
162
266
|
}): void;
|
|
163
|
-
/** Select every region in the table (and highlight them on the diagram). */
|
|
164
|
-
protected selectAllRegions(): void
|
|
267
|
+
/** Select every region in the table (and highlight them on the diagram), the source's taken. */
|
|
268
|
+
protected selectAllRegions(): Promise<void>;
|
|
165
269
|
protected deleteSelectedRegions(): void;
|
|
166
270
|
protected clearAllRegions(): void;
|
|
271
|
+
/** Delete every feature still in the slice's region source (with "Delete all regions"). */
|
|
272
|
+
private deleteAllSourceFeatures;
|
|
167
273
|
protected deleteRegion(shapeIdx: number): void;
|
|
168
274
|
private clampPaginatorFirst;
|
|
169
275
|
protected changeShowShapeLabel(showLabel: boolean): void;
|
|
@@ -198,9 +304,15 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
198
304
|
* labels are ignored. (jit-ui#70)
|
|
199
305
|
*/
|
|
200
306
|
private syncClassesFromRegions;
|
|
201
|
-
/**
|
|
307
|
+
/**
|
|
308
|
+
* Whether the classes count every slice of the stack: in a volume view (the whole stack on
|
|
309
|
+
* screen), unless its slice pane shows one slice. The table lists the slice's regions anyway.
|
|
310
|
+
*/
|
|
311
|
+
private get stackCounts();
|
|
312
|
+
/** Rebuild the per-class region counts shown in the panel (the stack's, see stackCounts). */
|
|
202
313
|
private recomputeClassCounts;
|
|
203
|
-
/** Rebuild the panel's display order — most-used classes first, then by name.
|
|
314
|
+
/** Rebuild the panel's display order — most-used classes first, then by name. A class only
|
|
315
|
+
* the region source has is listed too, in its colour. */
|
|
204
316
|
private updateDisplayClasses;
|
|
205
317
|
/** Number of regions currently using a class (keyed by the active match mode). */
|
|
206
318
|
protected classCount(name: string): number;
|
|
@@ -237,7 +349,11 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
237
349
|
/** Validate and apply an imported annotation-classes JSON file. */
|
|
238
350
|
private applyImportedPresets;
|
|
239
351
|
protected importRois(event: Event): void;
|
|
240
|
-
/**
|
|
352
|
+
/**
|
|
353
|
+
* Replace the regions with an imported GeoJSON file's, and the slice's region source with them.
|
|
354
|
+
* A large file becomes the slice's region source instead (drawn by level of detail; listed above
|
|
355
|
+
* the table), the table emptied.
|
|
356
|
+
*/
|
|
241
357
|
private applyImportedRois;
|
|
242
358
|
/** Regions to serialize on save/export (every slice for a combined z-stack). */
|
|
243
359
|
private regionsForSave;
|
|
@@ -268,5 +384,5 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
268
384
|
protected cancelSaveAs(): void;
|
|
269
385
|
private toast;
|
|
270
386
|
static ɵfac: i0.ɵɵFactoryDeclaration<RegionEditorComponent, never>;
|
|
271
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<RegionEditorComponent, "region-editor", never, {}, {}, never, never, true, never>;
|
|
387
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RegionEditorComponent, "region-editor", never, { "active": { "alias": "active"; "required": false; }; }, {}, never, never, true, never>;
|
|
272
388
|
}
|
|
@@ -4,6 +4,8 @@ import { IImageMetadata } from '../contracts/image.contract';
|
|
|
4
4
|
export interface PixelSize {
|
|
5
5
|
mppX?: number;
|
|
6
6
|
mppY?: number;
|
|
7
|
+
/** Spacing between slices (µm), when the stack declares it. */
|
|
8
|
+
mppZ?: number;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* Choose the physical pixel size for area display from the image meta. The
|
|
@@ -24,3 +26,9 @@ export declare function regionAreaPx(region: Pick<Region, 'bounds'>): number;
|
|
|
24
26
|
* otherwise px². Empty for a degenerate (non-positive) area.
|
|
25
27
|
*/
|
|
26
28
|
export declare function formatArea(px: number, mpp?: PixelSize): string;
|
|
29
|
+
/**
|
|
30
|
+
* A volume in px² × slices for display: mm³ (three significant digits) from 0.001 mm³, µm³ below,
|
|
31
|
+
* when the pixel size and the slice spacing are known; otherwise voxels (one pixel by one slice).
|
|
32
|
+
* Empty for a non-positive volume.
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatVolume(pxSlices: number, mpp?: PixelSize): string;
|
|
@@ -43,8 +43,14 @@ export declare class RegionPersistenceService {
|
|
|
43
43
|
* "does not exist" and later checks keep working.
|
|
44
44
|
*/
|
|
45
45
|
fileExists(names: Observable<string>): Observable<boolean>;
|
|
46
|
-
/**
|
|
47
|
-
|
|
46
|
+
/**
|
|
47
|
+
* `regions` as GeoJSON, merged with the image's region source when it has one (the source's
|
|
48
|
+
* features that were not taken or deleted, then `regions`); `slice` names a folder stack's
|
|
49
|
+
* slice.
|
|
50
|
+
*/
|
|
51
|
+
serialize(regions: Region[], slice?: number): Promise<string>;
|
|
52
|
+
/** Download `regions` (with the region source behind them) as a GeoJSON file named `filename`. */
|
|
53
|
+
download(regions: Region[], filename: string): Promise<void>;
|
|
48
54
|
/**
|
|
49
55
|
* Save `regions()` to the host as `filename`. Serializing is deferred one
|
|
50
56
|
* tick (so a progress indicator paints before a large synchronous
|
|
@@ -56,9 +62,11 @@ export declare class RegionPersistenceService {
|
|
|
56
62
|
* A folder stack's regions as one geojson per slice-file (jit-ui#93), each
|
|
57
63
|
* serialized on the default plane (z=0): every slice-file is one plane, and
|
|
58
64
|
* the loader re-derives the slice index from the file's position. Slices
|
|
59
|
-
* cleared since load are included (empty) so their file is overwritten
|
|
65
|
+
* cleared since load are included (empty) so their file is overwritten, and so are slices
|
|
66
|
+
* whose region source lost features; a slice with a region source keeps the features still
|
|
67
|
+
* in it.
|
|
60
68
|
*/
|
|
61
|
-
sliceGeoJsons(): SliceGeoJson[]
|
|
69
|
+
sliceGeoJsons(): Promise<SliceGeoJson[]>;
|
|
62
70
|
/** Write per-slice geojsons through the host port. */
|
|
63
71
|
saveSlices(slices: SliceGeoJson[]): Observable<void>;
|
|
64
72
|
/** Read the file chosen in a file input's change event as text, then call
|
|
@@ -40,6 +40,11 @@ export declare class RegionTableComponent implements OnChanges {
|
|
|
40
40
|
defaultColor: string;
|
|
41
41
|
/** Pixel size for the area column. */
|
|
42
42
|
mpp: PixelSize;
|
|
43
|
+
/**
|
|
44
|
+
* In a volume view, each class's volume over the whole stack (px² × slices; null while it is
|
|
45
|
+
* computed): the column shows the row's class volume instead of its area. Null: areas.
|
|
46
|
+
*/
|
|
47
|
+
volumes: ReadonlyMap<string, number | null> | null;
|
|
43
48
|
/** Rows whose label is being edited → the typed draft. A new map per start/stop. */
|
|
44
49
|
labelDrafts: Map<Region, string>;
|
|
45
50
|
/** A row's pencil: start editing its label. */
|
|
@@ -63,13 +68,14 @@ export declare class RegionTableComponent implements OnChanges {
|
|
|
63
68
|
deleteRow: EventEmitter<number>;
|
|
64
69
|
/** The paginator moved or changed its page size. */
|
|
65
70
|
pageChange: EventEmitter<RegionPage>;
|
|
66
|
-
/** Per row of {@link page}: its class swatch colour and formatted area
|
|
67
|
-
* an input changes instead of per check (the area walks the region's geometry). */
|
|
71
|
+
/** Per row of {@link page}: its class swatch colour and formatted area (or class volume),
|
|
72
|
+
* derived when an input changes instead of per check (the area walks the region's geometry). */
|
|
68
73
|
protected rowView: Map<Region, {
|
|
69
74
|
color: string;
|
|
70
|
-
|
|
75
|
+
measure: string;
|
|
71
76
|
}>;
|
|
72
77
|
ngOnChanges(): void;
|
|
78
|
+
private measure;
|
|
73
79
|
private classColor;
|
|
74
80
|
private area;
|
|
75
81
|
protected startEdit(region: Region, event: Event): void;
|
|
@@ -79,5 +85,5 @@ export declare class RegionTableComponent implements OnChanges {
|
|
|
79
85
|
rows?: number;
|
|
80
86
|
}): void;
|
|
81
87
|
static ɵfac: i0.ɵɵFactoryDeclaration<RegionTableComponent, never>;
|
|
82
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<RegionTableComponent, "region-table", never, { "page": { "alias": "page"; "required": false; }; "total": { "alias": "total"; "required": false; }; "first": { "alias": "first"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "rowsPerPageOptions": { "alias": "rowsPerPageOptions"; "required": false; }; "metaKey": { "alias": "metaKey"; "required": false; }; "selection": { "alias": "selection"; "required": false; }; "presetSet": { "alias": "presetSet"; "required": false; }; "defaultColor": { "alias": "defaultColor"; "required": false; }; "mpp": { "alias": "mpp"; "required": false; }; "labelDrafts": { "alias": "labelDrafts"; "required": false; }; }, { "selectionChange": "selectionChange"; "rowSelect": "rowSelect"; "labelEditStart": "labelEditStart"; "labelDraftChange": "labelDraftChange"; "labelEditStop": "labelEditStop"; "classPick": "classPick"; "deleteRow": "deleteRow"; "pageChange": "pageChange"; }, never, never, true, never>;
|
|
88
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RegionTableComponent, "region-table", never, { "page": { "alias": "page"; "required": false; }; "total": { "alias": "total"; "required": false; }; "first": { "alias": "first"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "rowsPerPageOptions": { "alias": "rowsPerPageOptions"; "required": false; }; "metaKey": { "alias": "metaKey"; "required": false; }; "selection": { "alias": "selection"; "required": false; }; "presetSet": { "alias": "presetSet"; "required": false; }; "defaultColor": { "alias": "defaultColor"; "required": false; }; "mpp": { "alias": "mpp"; "required": false; }; "volumes": { "alias": "volumes"; "required": false; }; "labelDrafts": { "alias": "labelDrafts"; "required": false; }; }, { "selectionChange": "selectionChange"; "rowSelect": "rowSelect"; "labelEditStart": "labelEditStart"; "labelDraftChange": "labelDraftChange"; "labelEditStop": "labelEditStop"; "classPick": "classPick"; "deleteRow": "deleteRow"; "pageChange": "pageChange"; }, never, never, true, never>;
|
|
83
89
|
}
|
|
@@ -70,16 +70,17 @@ export interface ContainsOptions {
|
|
|
70
70
|
*/
|
|
71
71
|
export declare function regionContains(region: Pick<Region, 'bounds'>, x: number, y: number, opts?: ContainsOptions): boolean;
|
|
72
72
|
/** Index of the topmost (last) region containing (x, y), or -1. */
|
|
73
|
-
export declare function topmostRegionAt
|
|
74
|
-
skip?: (r:
|
|
73
|
+
export declare function topmostRegionAt<R extends Pick<Region, 'bounds'>>(regions: ReadonlyArray<R>, x: number, y: number, opts?: ContainsOptions & {
|
|
74
|
+
skip?: (r: R) => boolean;
|
|
75
75
|
}): number;
|
|
76
76
|
/**
|
|
77
77
|
* Indices of every region whose bounding box intersects the world box
|
|
78
78
|
* [x0,y0]–[x1,y1] (rubber-band selection). `skipProfiles` leaves out
|
|
79
|
-
* intensity-profile lines.
|
|
79
|
+
* intensity-profile lines, `skip` any other region.
|
|
80
80
|
*/
|
|
81
81
|
export declare function regionsInRect(regions: ReadonlyArray<Region>, x0: number, y0: number, x1: number, y1: number, opts?: {
|
|
82
82
|
skipProfiles?: boolean;
|
|
83
|
+
skip?: (r: Region) => boolean;
|
|
83
84
|
}): number[];
|
|
84
85
|
/** The handle offsets a bézier ring is drawn with; absent arrays fall back to the default. */
|
|
85
86
|
export interface RingHandleOffsets {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Draws a region source (see `region-source`) under the editable regions, at the level of detail
|
|
3
|
+
* the zoom calls for, from the tiles in view only — the way the spatial views draw cell outlines.
|
|
4
|
+
* Shared by the OpenSeadragon and napari overlays: both hand it their svg and their world → svg
|
|
5
|
+
* camera affine, as they do their {@link SvgRegionRenderer}.
|
|
6
|
+
*
|
|
7
|
+
* One `<path>` per colour (every ring of every feature of that colour, even-odd), in world
|
|
8
|
+
* coordinates inside one transformed group, so a camera move rewrites one attribute. The tiles in
|
|
9
|
+
* view are re-planned once the camera settles; while a finer tile loads its coarser parent is
|
|
10
|
+
* drawn instead, so zooming in sharpens the outlines rather than blanking them. Features taken
|
|
11
|
+
* into the working set (selected, edited) or deleted are not drawn: the region renderer draws the
|
|
12
|
+
* taken ones as ordinary regions.
|
|
13
|
+
*
|
|
14
|
+
* It also answers what is under a point, from the features drawn, for the overlays' selection.
|
|
15
|
+
*/
|
|
16
|
+
import type { Observable } from 'rxjs';
|
|
17
|
+
import { RegionSourceView } from '../region-source/region-source';
|
|
18
|
+
import { TileFeature } from '../region-source/region-tiles';
|
|
19
|
+
import { Affine } from './svg-region-renderer';
|
|
20
|
+
/** Wait this long after the last camera change before planning tiles (ms). */
|
|
21
|
+
export declare const SOURCE_REPLAN_MS = 90;
|
|
22
|
+
/** The view is padded by this fraction on each side, so a short pan finds its tiles loaded. */
|
|
23
|
+
export declare const SOURCE_VIEW_MARGIN = 0.25;
|
|
24
|
+
/** At most this many tiles in view. */
|
|
25
|
+
export declare const SOURCE_MAX_TILES = 256;
|
|
26
|
+
/** A rubber band takes at most this many source features into the working set. */
|
|
27
|
+
export declare const SOURCE_MARQUEE_LIMIT = 2000;
|
|
28
|
+
/** The svg size (local px), for the part of the world in view. */
|
|
29
|
+
export type SvgSize = () => {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
};
|
|
33
|
+
export declare class RegionSourceLayer {
|
|
34
|
+
private readonly svg;
|
|
35
|
+
private readonly size;
|
|
36
|
+
private readonly group;
|
|
37
|
+
private camera;
|
|
38
|
+
/** Class labels inside the features, in screen space over the outlines. */
|
|
39
|
+
private readonly labelLayer;
|
|
40
|
+
/** Class name → depth in the source's class hierarchy (parents draw under their children). */
|
|
41
|
+
private depthOf;
|
|
42
|
+
/** Class name → its parent class in the source's class hierarchy. */
|
|
43
|
+
private parentOf;
|
|
44
|
+
private view;
|
|
45
|
+
private visible;
|
|
46
|
+
private readonly sub;
|
|
47
|
+
/** Loaded tiles of the current source and plane, by id, least recently used first. */
|
|
48
|
+
private readonly tiles;
|
|
49
|
+
/** The tiles the view wants now. */
|
|
50
|
+
private wanted;
|
|
51
|
+
/** The features drawn, by id (each at the finest level loaded). */
|
|
52
|
+
private drawn;
|
|
53
|
+
private loading;
|
|
54
|
+
private replanTimer;
|
|
55
|
+
private drawFrame;
|
|
56
|
+
constructor(svg: SVGSVGElement, view$: Observable<RegionSourceView | null>, size?: SvgSize);
|
|
57
|
+
/** Follow the camera: rewrite the transform now, re-plan the tiles once it settles. */
|
|
58
|
+
setCamera(affine: Affine): void;
|
|
59
|
+
/** Show or hide the source with the regions. */
|
|
60
|
+
setVisible(visible: boolean): void;
|
|
61
|
+
/**
|
|
62
|
+
* The source feature under world point (x, y) — inside an area, or within `tolerancePx`
|
|
63
|
+
* screen pixels of a polyline — from the features drawn; the innermost of nested ones.
|
|
64
|
+
*/
|
|
65
|
+
featureAt(x: number, y: number, tolerancePx?: number): TileFeature | null;
|
|
66
|
+
/** The drawn source features whose box meets the world box (the rubber band's rule). */
|
|
67
|
+
featuresInRect(x0: number, y0: number, x1: number, y1: number): TileFeature[];
|
|
68
|
+
destroy(): void;
|
|
69
|
+
private setView;
|
|
70
|
+
/** The layer is the svg's first child (under the regions) while it shows a source. */
|
|
71
|
+
private attach;
|
|
72
|
+
private applyCamera;
|
|
73
|
+
/** Screen px per world unit. */
|
|
74
|
+
private scale;
|
|
75
|
+
/** The world box in view, padded by the margin; null when the svg has no size yet. */
|
|
76
|
+
private viewRect;
|
|
77
|
+
/** Work out the tiles the view needs, draw what is loaded, and load the rest. */
|
|
78
|
+
private replan;
|
|
79
|
+
private keep;
|
|
80
|
+
private scheduleDraw;
|
|
81
|
+
/**
|
|
82
|
+
* Rebuild the paths from the wanted tiles that are loaded, a missing tile's nearest loaded
|
|
83
|
+
* ancestor standing in for it; each feature once, at the finest level loaded.
|
|
84
|
+
*/
|
|
85
|
+
private draw;
|
|
86
|
+
/**
|
|
87
|
+
* The drawn features as paths: one per colour when outlined; filled, in paint order — parents
|
|
88
|
+
* (by the class hierarchy) and then larger features first, so what lies inside paints over
|
|
89
|
+
* them — one path per run of a colour.
|
|
90
|
+
*/
|
|
91
|
+
private runs;
|
|
92
|
+
/** Class labels inside the drawn features (each part where it fits), when labels are on. */
|
|
93
|
+
private drawLabels;
|
|
94
|
+
/** The loaded tile for `key`, else its nearest loaded coarser ancestor. */
|
|
95
|
+
private loadedOrAncestor;
|
|
96
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How regions are drawn, shared by the OpenSeadragon and napari overlays and the region-source
|
|
3
|
+
* layer, so a feature looks the same before and after it is taken into the regions.
|
|
4
|
+
*
|
|
5
|
+
* Two looks: **outlines** (the default — each region stroked in its colour, filled only while
|
|
6
|
+
* selected) and **filled**, an atlas's look (each region filled in its colour, with thin outlines,
|
|
7
|
+
* the selection in a highlight colour, labels centred inside each part).
|
|
8
|
+
*/
|
|
9
|
+
import { Region } from '../models/region';
|
|
10
|
+
import type { Project, ScreenLayer } from './svg-region-renderer';
|
|
11
|
+
/** The region look (see the module doc). */
|
|
12
|
+
export interface RegionStyle {
|
|
13
|
+
/** Fill each region at this opacity; 0 draws outlines only. */
|
|
14
|
+
fillOpacity: number;
|
|
15
|
+
/** Outline colour of a filled region; null: its own colour. */
|
|
16
|
+
stroke: string | null;
|
|
17
|
+
/** Outline width of a filled region, screen px; null: 1. */
|
|
18
|
+
strokeWidth: number | null;
|
|
19
|
+
/** Fill colour of a selected filled region; null: {@link DEFAULT_HIGHLIGHT}. */
|
|
20
|
+
highlight: string | null;
|
|
21
|
+
}
|
|
22
|
+
export declare const DEFAULT_REGION_STYLE: RegionStyle;
|
|
23
|
+
/** A selected region's fill in the filled look, unless the style names one (the Allen atlas's). */
|
|
24
|
+
export declare const DEFAULT_HIGHLIGHT = "#a020f0";
|
|
25
|
+
/** Whether `style` is the filled look. */
|
|
26
|
+
export declare function isFilled(style: RegionStyle): boolean;
|
|
27
|
+
/** The paint of one region shape. */
|
|
28
|
+
export interface ShapePaint {
|
|
29
|
+
fill: string;
|
|
30
|
+
fillOpacity: number;
|
|
31
|
+
stroke: string;
|
|
32
|
+
strokeWidth: number;
|
|
33
|
+
}
|
|
34
|
+
/** The paint of a region of colour `color`, selected or not, in `style`. */
|
|
35
|
+
export declare function shapePaint(color: string, selected: boolean, style?: RegionStyle): ShapePaint;
|
|
36
|
+
/** Set `paint` on an SVG shape. */
|
|
37
|
+
export declare function applyPaint(el: SVGElement, paint: ShapePaint): void;
|
|
38
|
+
/** A point to label a part at, and the room around it (image px). */
|
|
39
|
+
export interface LabelSpot {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
room: number;
|
|
43
|
+
}
|
|
44
|
+
/** Where to label `region`: each part's pole of inaccessibility (a rectangle's centre). */
|
|
45
|
+
export declare function regionLabelSpots(region: Region): LabelSpot[];
|
|
46
|
+
/**
|
|
47
|
+
* A class label centred at `spot`, shown only while it fits: the room around the spot, on screen,
|
|
48
|
+
* at least half the text's width (and a few pixels). Re-checked on every camera move.
|
|
49
|
+
*/
|
|
50
|
+
export declare function placeInsideLabel(layer: ScreenLayer, text: string, spot: LabelSpot, color?: string): SVGTextElement;
|
|
51
|
+
/** Whether a label `halfWidth` px wide fits around `spot` through `project`. */
|
|
52
|
+
export declare function labelFits(project: Project, spot: LabelSpot, halfWidth: number): boolean;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A {@link RegionSource} served over HTTP, by a server that tiles a region set as `region-tiles`
|
|
3
|
+
* does (the example tile server's `/regions/…` routes). Relative to the source's base URL:
|
|
4
|
+
*
|
|
5
|
+
* - `GET info` → {@link RegionSourceInfo}
|
|
6
|
+
* - `GET tile/{z}/{level}/{gx}/{gy}` → `{ features: WireTileFeature[] }`
|
|
7
|
+
* - `POST features` `{ ids }` → `{ features: SourceFeature[] }`
|
|
8
|
+
* - `POST index` `{ z, ...query }` → {@link RegionIndexPage}
|
|
9
|
+
* - `POST classes` `{ z, exclude }` → features per class on plane z
|
|
10
|
+
* - `POST outlines` `{ classes, level, exclude }` → `{ slices: [{ z, rings }] }`
|
|
11
|
+
* - `POST export` `{ exclude, extra }`→ a GeoJSON FeatureCollection
|
|
12
|
+
*
|
|
13
|
+
* Tile rings travel as flat `[x, y, x, y, …]` arrays, label points as flat `[x, y, room, …]`.
|
|
14
|
+
*
|
|
15
|
+
* Given the host's Angular `HttpClient` (as the visualizer passes it), every request goes through
|
|
16
|
+
* it, so the host's interceptors apply — its auth header above all — as for the image tiles and
|
|
17
|
+
* the spatial data. The library itself knows nothing of authentication.
|
|
18
|
+
*/
|
|
19
|
+
import type { HttpClient } from '@angular/common/http';
|
|
20
|
+
import { RegionSource } from './region-source';
|
|
21
|
+
import type { Bbox } from './region-tiles';
|
|
22
|
+
/** A tile feature on the wire: rings as plain arrays. */
|
|
23
|
+
export interface WireTileFeature {
|
|
24
|
+
id: string;
|
|
25
|
+
label: string | null;
|
|
26
|
+
color: string | null;
|
|
27
|
+
bbox: Bbox;
|
|
28
|
+
rings: number[][];
|
|
29
|
+
open?: boolean;
|
|
30
|
+
labels?: number[];
|
|
31
|
+
}
|
|
32
|
+
/** Options of {@link openHttpRegionSource}. */
|
|
33
|
+
export interface HttpRegionSourceOptions {
|
|
34
|
+
/**
|
|
35
|
+
* The host's `HttpClient`: requests then go through it and its interceptors (the host's auth),
|
|
36
|
+
* not `fetch`, and `init` and `fetch` are not used.
|
|
37
|
+
*/
|
|
38
|
+
http?: HttpClient;
|
|
39
|
+
/** Extra request options (credentials, headers) for every `fetch` request. */
|
|
40
|
+
init?: RequestInit;
|
|
41
|
+
/** The fetch to use (default the global one). */
|
|
42
|
+
fetch?: typeof fetch;
|
|
43
|
+
}
|
|
44
|
+
/** Open the region source at `baseUrl` (its `info` is fetched first). */
|
|
45
|
+
export declare function openHttpRegionSource(baseUrl: string, options?: HttpRegionSourceOptions): Promise<RegionSource>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The region-source worker's protocol and the tables it holds, shared by the worker and the
|
|
3
|
+
* main-thread fallback (which runs the very same {@link RegionSourceTables} where no worker can
|
|
4
|
+
* start).
|
|
5
|
+
*
|
|
6
|
+
* Protocol: `{ id, op, ...args }` → `{ id, ok: true, result }` | `{ id, ok: false, error }`.
|
|
7
|
+
*/
|
|
8
|
+
import { ReconstructOptions, SliceOutlines } from '../geometry/reconstruct';
|
|
9
|
+
import type { Mesh } from 'napari-js/geometry';
|
|
10
|
+
import { ClassOutlines, RegionIndexPage, RegionIndexQuery, RegionSourceInfo, RegionTile } from './region-tiles';
|
|
11
|
+
import type { SourceFeature } from './region-source';
|
|
12
|
+
export type RegionSourceRequest = {
|
|
13
|
+
op: 'open';
|
|
14
|
+
text: string;
|
|
15
|
+
tileSize?: number;
|
|
16
|
+
} | {
|
|
17
|
+
op: 'tile';
|
|
18
|
+
handle: number;
|
|
19
|
+
z: number;
|
|
20
|
+
level: number;
|
|
21
|
+
gx: number;
|
|
22
|
+
gy: number;
|
|
23
|
+
} | {
|
|
24
|
+
op: 'features';
|
|
25
|
+
handle: number;
|
|
26
|
+
ids: readonly string[];
|
|
27
|
+
} | {
|
|
28
|
+
op: 'index';
|
|
29
|
+
handle: number;
|
|
30
|
+
z: number;
|
|
31
|
+
query: RegionIndexQuery;
|
|
32
|
+
} | {
|
|
33
|
+
op: 'classes';
|
|
34
|
+
handle: number;
|
|
35
|
+
z: number | null;
|
|
36
|
+
exclude?: readonly string[];
|
|
37
|
+
} | {
|
|
38
|
+
op: 'outlines';
|
|
39
|
+
handle: number;
|
|
40
|
+
classes: readonly string[] | null;
|
|
41
|
+
level: number;
|
|
42
|
+
exclude?: readonly string[];
|
|
43
|
+
} | {
|
|
44
|
+
op: 'mesh';
|
|
45
|
+
slices: readonly SliceOutlines[];
|
|
46
|
+
options?: ReconstructOptions;
|
|
47
|
+
} | {
|
|
48
|
+
op: 'export';
|
|
49
|
+
handle: number;
|
|
50
|
+
exclude: readonly string[];
|
|
51
|
+
extra: readonly object[];
|
|
52
|
+
} | {
|
|
53
|
+
op: 'close';
|
|
54
|
+
handle: number;
|
|
55
|
+
};
|
|
56
|
+
export interface RegionSourceResults {
|
|
57
|
+
open: {
|
|
58
|
+
handle: number;
|
|
59
|
+
info: RegionSourceInfo;
|
|
60
|
+
};
|
|
61
|
+
tile: RegionTile;
|
|
62
|
+
features: SourceFeature[];
|
|
63
|
+
index: RegionIndexPage;
|
|
64
|
+
classes: Record<string, number>;
|
|
65
|
+
outlines: ClassOutlines[];
|
|
66
|
+
mesh: Mesh;
|
|
67
|
+
export: string;
|
|
68
|
+
close: null;
|
|
69
|
+
}
|
|
70
|
+
export type RegionSourceMessage = RegionSourceRequest & {
|
|
71
|
+
id: number;
|
|
72
|
+
};
|
|
73
|
+
export type RegionSourceReply = {
|
|
74
|
+
id: number;
|
|
75
|
+
ok: true;
|
|
76
|
+
result: unknown;
|
|
77
|
+
} | {
|
|
78
|
+
id: number;
|
|
79
|
+
ok: false;
|
|
80
|
+
error: string;
|
|
81
|
+
};
|
|
82
|
+
/** The open tables, by handle. */
|
|
83
|
+
export declare class RegionSourceTables {
|
|
84
|
+
private readonly tables;
|
|
85
|
+
private nextHandle;
|
|
86
|
+
run<R extends RegionSourceRequest>(request: R): RegionSourceResults[R['op']];
|
|
87
|
+
private dispatch;
|
|
88
|
+
private table;
|
|
89
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory for the region-source Web Worker, isolated in its own module so the `import.meta.url`
|
|
3
|
+
* reference — which the bundler needs in order to locate the worker — is never pulled into the
|
|
4
|
+
* ts-jest CommonJS compile of anything that uses it. Same arrangement as
|
|
5
|
+
* `workers/spatial-math-worker.ts`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createRegionSourceWorker(): Worker;
|