@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
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A tiled region source: one image's large region set, served as level-of-detail tiles so a view
|
|
3
|
+
* never holds or draws the whole set (see `region-tiles` for the levels and tiles).
|
|
4
|
+
*
|
|
5
|
+
* Two implementations behind {@link RegionSource}: a GeoJSON source parsed and tiled in a Web
|
|
6
|
+
* Worker (`openGeoJsonRegionSource`, the main thread only ever sees tiles), and an HTTP source
|
|
7
|
+
* for a server that serves the same tiles (`openHttpRegionSource`).
|
|
8
|
+
*/
|
|
9
|
+
import type { ClassOutlines, GeoJsonFeatureLike, RegionIndexPage, RegionIndexQuery, RegionSourceInfo, RegionTile, RegionTileKey, TileFeature } from './region-tiles';
|
|
10
|
+
import type { RegionStyle } from '../region-overlay/region-style';
|
|
11
|
+
/** A feature's exact GeoJSON with the source's id for it. */
|
|
12
|
+
export interface SourceFeature {
|
|
13
|
+
id: string;
|
|
14
|
+
feature: GeoJsonFeatureLike;
|
|
15
|
+
}
|
|
16
|
+
/** One image's tiled region set. */
|
|
17
|
+
export interface RegionSource {
|
|
18
|
+
/** What the source holds; known once it is open. */
|
|
19
|
+
readonly info: RegionSourceInfo;
|
|
20
|
+
/** One tile of plane `z`. Cached: asking again for a tile in view costs nothing. */
|
|
21
|
+
getTile(z: number, key: RegionTileKey, signal?: AbortSignal): Promise<RegionTile>;
|
|
22
|
+
/** The exact features with these ids (unknown ids are skipped). */
|
|
23
|
+
getFeatures(ids: readonly string[]): Promise<SourceFeature[]>;
|
|
24
|
+
/** A page of plane `z`'s feature index. */
|
|
25
|
+
getIndex(z: number, query: RegionIndexQuery): Promise<RegionIndexPage>;
|
|
26
|
+
/**
|
|
27
|
+
* Every plane's outlines of the features of these classes, simplified for `level`, without the
|
|
28
|
+
* `exclude`d ids: what a 3D reconstruction of the classes stacks. `classes` null reads every
|
|
29
|
+
* class, each outline labelled with its own (what a section through the stack draws).
|
|
30
|
+
*/
|
|
31
|
+
getClassOutlines(classes: readonly string[] | null, level: number, exclude?: readonly string[]): Promise<ClassOutlines[]>;
|
|
32
|
+
/**
|
|
33
|
+
* How many features of each class plane `z` has (null: every plane, the whole stack), without
|
|
34
|
+
* the `exclude`d ids.
|
|
35
|
+
*/
|
|
36
|
+
getClassCounts(z: number | null, exclude?: readonly string[]): Promise<Record<string, number>>;
|
|
37
|
+
/**
|
|
38
|
+
* The whole set as a GeoJSON FeatureCollection string, through the working set: `exclude`d
|
|
39
|
+
* features (taken for editing, or deleted) left out, `extra` features appended.
|
|
40
|
+
*/
|
|
41
|
+
exportGeoJson(exclude: readonly string[], extra: readonly object[]): Promise<string>;
|
|
42
|
+
/** Release the source (its worker table, its cache). */
|
|
43
|
+
dispose(): void;
|
|
44
|
+
}
|
|
45
|
+
/** What the store shows of the current slice's region source: what a source layer draws. */
|
|
46
|
+
export interface RegionSourceView {
|
|
47
|
+
source: RegionSource;
|
|
48
|
+
/** The source plane the slice shows. */
|
|
49
|
+
plane: number;
|
|
50
|
+
/** Ids the source no longer draws: taken into the working set, or deleted. */
|
|
51
|
+
taken: ReadonlySet<string>;
|
|
52
|
+
/** The colour a feature is drawn in (its class colour, as a region of that class gets). */
|
|
53
|
+
colorOf(feature: Pick<TileFeature, 'label' | 'color'>): string;
|
|
54
|
+
/** The region look, the regions' own (so a feature looks the same once taken). */
|
|
55
|
+
style: RegionStyle;
|
|
56
|
+
/** Whether class labels are shown. */
|
|
57
|
+
labels: boolean;
|
|
58
|
+
/** Whether a class's features are hidden (see `RegionStore.setClassesHidden`); default: none is. */
|
|
59
|
+
isHidden?(label: string | null | undefined): boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* ROI GeoJSON at least this many characters long loads as a tiled region source rather than as
|
|
63
|
+
* regions (see `VizConfig.regionSourceMinChars`).
|
|
64
|
+
*/
|
|
65
|
+
export declare const REGION_SOURCE_MIN_CHARS = 1000000;
|
|
66
|
+
/** Tiles a source keeps, most recently used last. */
|
|
67
|
+
export declare const REGION_TILE_CACHE_SIZE = 384;
|
|
68
|
+
/** A least-recently-used cache of tile requests. A request that fails is forgotten. */
|
|
69
|
+
export declare class RegionTileCache {
|
|
70
|
+
private readonly limit;
|
|
71
|
+
private readonly tiles;
|
|
72
|
+
constructor(limit?: number);
|
|
73
|
+
/** The cached tile, else `load()`'s, cached. */
|
|
74
|
+
get(z: number, key: RegionTileKey, load: () => Promise<RegionTile>): Promise<RegionTile>;
|
|
75
|
+
clear(): void;
|
|
76
|
+
}
|
|
77
|
+
/** An `AbortError`, as `fetch` and the workers reject with. */
|
|
78
|
+
export declare function abortError(): Error;
|
|
79
|
+
/** True for the rejection of an aborted request. */
|
|
80
|
+
export declare function isAbortError(err: unknown): boolean;
|
|
81
|
+
/** `promise`, rejected with an `AbortError` as soon as `signal` fires (the work goes on). */
|
|
82
|
+
export declare function abortable<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/** An axis-aligned box `[x0, y0, x1, y1]` in image pixels. */
|
|
2
|
+
export type Bbox = [number, number, number, number];
|
|
3
|
+
/** Edge of a level-0 tile, in image pixels. */
|
|
4
|
+
export declare const REGION_TILE_SIZE = 512;
|
|
5
|
+
/**
|
|
6
|
+
* One class of a class hierarchy (e.g. a brain-atlas ontology): the class name the features use,
|
|
7
|
+
* its long name, its parent class and its colour. A region set may carry one (a GeoJSON
|
|
8
|
+
* FeatureCollection's `classHierarchy` member); the Region Editor then lists the set as a tree.
|
|
9
|
+
*/
|
|
10
|
+
export interface RegionClassNode {
|
|
11
|
+
/** The class name, as features use it (`classification.name`): an atlas acronym, say. */
|
|
12
|
+
name: string;
|
|
13
|
+
/** The long name, e.g. "Somatomotor areas, Layer 5". */
|
|
14
|
+
title?: string;
|
|
15
|
+
/** The parent class's name; absent for a root. */
|
|
16
|
+
parent?: string | null;
|
|
17
|
+
/** `#rrggbb`. */
|
|
18
|
+
color?: string;
|
|
19
|
+
/** Position among its siblings (an atlas's graph order); file order without one. */
|
|
20
|
+
order?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* How a region set wants to be drawn, a hint the viewer applies when the set opens (a GeoJSON
|
|
24
|
+
* FeatureCollection's `style` member): an atlas fills its structures and labels them.
|
|
25
|
+
*/
|
|
26
|
+
export interface RegionSourceStyle {
|
|
27
|
+
/** Fill regions in their colour at this opacity (0 = outlines only). */
|
|
28
|
+
fillOpacity?: number;
|
|
29
|
+
/** Outline colour when filled (default: the region's colour). */
|
|
30
|
+
stroke?: string;
|
|
31
|
+
/** Outline width in screen px. */
|
|
32
|
+
strokeWidth?: number;
|
|
33
|
+
/** Show class labels inside the regions. */
|
|
34
|
+
labels?: boolean;
|
|
35
|
+
/** Fill colour of selected regions. */
|
|
36
|
+
highlight?: string;
|
|
37
|
+
}
|
|
38
|
+
/** What a region source holds, known once it is open. */
|
|
39
|
+
export interface RegionSourceInfo {
|
|
40
|
+
/** Features in the source, over every plane. */
|
|
41
|
+
featureCount: number;
|
|
42
|
+
/** The box around every feature's geometry; null when none has any. */
|
|
43
|
+
bounds: Bbox | null;
|
|
44
|
+
/** Edge of a level-0 tile, in image pixels. */
|
|
45
|
+
tileSize: number;
|
|
46
|
+
/** Number of levels; the last one's tiles cover {@link bounds} in a few tiles. */
|
|
47
|
+
levels: number;
|
|
48
|
+
/** The z planes features are on (QuPath's `geometry.plane.z`, 0 without one), ascending. */
|
|
49
|
+
planes: number[];
|
|
50
|
+
/** The colour the file gives each class (its first feature's), by class name. */
|
|
51
|
+
classColors: Record<string, string>;
|
|
52
|
+
/** The set's class hierarchy, when it has one. */
|
|
53
|
+
hierarchy?: RegionClassNode[];
|
|
54
|
+
/** How the set wants to be drawn, when it says. */
|
|
55
|
+
style?: RegionSourceStyle;
|
|
56
|
+
}
|
|
57
|
+
/** One feature as a tile carries it: identity, class and outline at the tile's level. */
|
|
58
|
+
export interface TileFeature {
|
|
59
|
+
id: string;
|
|
60
|
+
/** The class name. */
|
|
61
|
+
label: string | null;
|
|
62
|
+
/** The feature's own colour (`#rrggbb`), from its classification. */
|
|
63
|
+
color: string | null;
|
|
64
|
+
/** The box around the exact geometry. */
|
|
65
|
+
bbox: Bbox;
|
|
66
|
+
/** Rings as interleaved `x, y` (no repeated closing vertex): exteriors and holes of every
|
|
67
|
+
* part, drawn and hit-tested even-odd. For an open feature, its polylines. */
|
|
68
|
+
rings: Float32Array[];
|
|
69
|
+
/** A polyline (LineString) rather than an area. */
|
|
70
|
+
open: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Where to label the feature, per part big enough: `x, y, room` triples, `room` the distance
|
|
73
|
+
* from the point to the part's nearest edge (image px), so a label shows once it fits.
|
|
74
|
+
*/
|
|
75
|
+
labels?: Float32Array;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A class's outlines on one plane: rings as interleaved `x, y` image px (holes included), and its
|
|
79
|
+
* open features' polylines, likewise (absent from a server that predates them). Read for every
|
|
80
|
+
* class at once, each ring's and line's class comes with it (`ringLabels`, `lineLabels`).
|
|
81
|
+
*/
|
|
82
|
+
export interface ClassOutlines {
|
|
83
|
+
z: number;
|
|
84
|
+
rings: Float32Array[];
|
|
85
|
+
/**
|
|
86
|
+
* The feature each ring is part of (see SliceOutlines.ringGroups): a feature's rings fill
|
|
87
|
+
* even-odd, the features as their union. Absent from a server that predates them.
|
|
88
|
+
*/
|
|
89
|
+
ringGroups?: number[];
|
|
90
|
+
lines?: Float32Array[];
|
|
91
|
+
ringLabels?: string[];
|
|
92
|
+
lineLabels?: string[];
|
|
93
|
+
}
|
|
94
|
+
/** One tile of one level of one plane. */
|
|
95
|
+
export interface RegionTile {
|
|
96
|
+
z: number;
|
|
97
|
+
level: number;
|
|
98
|
+
gx: number;
|
|
99
|
+
gy: number;
|
|
100
|
+
features: TileFeature[];
|
|
101
|
+
}
|
|
102
|
+
/** A tile's address. */
|
|
103
|
+
export interface RegionTileKey {
|
|
104
|
+
level: number;
|
|
105
|
+
gx: number;
|
|
106
|
+
gy: number;
|
|
107
|
+
}
|
|
108
|
+
/** One row of a source's feature index (the Region Editor's table). */
|
|
109
|
+
export interface RegionIndexRow {
|
|
110
|
+
id: string;
|
|
111
|
+
label: string | null;
|
|
112
|
+
color: string | null;
|
|
113
|
+
bbox: Bbox;
|
|
114
|
+
/** The area inside the exact outline (holes left out), image px²; 0 for a polyline. Absent from a
|
|
115
|
+
* server that predates it. */
|
|
116
|
+
area?: number;
|
|
117
|
+
}
|
|
118
|
+
/** A page of a plane's feature index. */
|
|
119
|
+
export interface RegionIndexPage {
|
|
120
|
+
/** Rows matching the query, over the whole plane. */
|
|
121
|
+
total: number;
|
|
122
|
+
rows: RegionIndexRow[];
|
|
123
|
+
}
|
|
124
|
+
/** Which rows a page of the index holds. */
|
|
125
|
+
export interface RegionIndexQuery {
|
|
126
|
+
offset: number;
|
|
127
|
+
limit: number;
|
|
128
|
+
/** Only rows whose class name contains this (case-insensitive). */
|
|
129
|
+
label?: string;
|
|
130
|
+
/** Leave these ids out (taken into the working set, or deleted). */
|
|
131
|
+
exclude?: readonly string[];
|
|
132
|
+
/** Only rows of exactly these classes. */
|
|
133
|
+
classes?: readonly string[];
|
|
134
|
+
}
|
|
135
|
+
/** The parts of a GeoJSON feature the tiler reads. Parsed from a file: nothing is guaranteed. */
|
|
136
|
+
export interface GeoJsonFeatureLike {
|
|
137
|
+
type?: string;
|
|
138
|
+
id?: string | number;
|
|
139
|
+
geometry?: {
|
|
140
|
+
type?: string;
|
|
141
|
+
coordinates?: unknown;
|
|
142
|
+
plane?: {
|
|
143
|
+
z?: number;
|
|
144
|
+
};
|
|
145
|
+
} | null;
|
|
146
|
+
properties?: {
|
|
147
|
+
id?: string | number;
|
|
148
|
+
classification?: unknown;
|
|
149
|
+
} & Record<string, unknown>;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The level whose tiles suit a zoom of `pxPerImagePx` screen pixels per image pixel: exact (0)
|
|
153
|
+
* at 1:1 and closer, else level k for zooms in [2⁻ᵏ, 2¹⁻ᵏ), where its tolerance is half to one
|
|
154
|
+
* screen pixel and the features it leaves out are under one or two.
|
|
155
|
+
*/
|
|
156
|
+
export declare function regionLevelFor(pxPerImagePx: number, levels: number): number;
|
|
157
|
+
/** Simplification tolerance of a level, in image pixels (0 = exact). */
|
|
158
|
+
export declare function levelTolerance(level: number): number;
|
|
159
|
+
/** Features smaller than this (their box's longer side, image pixels) are left out of a level. */
|
|
160
|
+
export declare function levelMinExtent(level: number): number;
|
|
161
|
+
/** Tile edge of a level, in image pixels. */
|
|
162
|
+
export declare function levelTileSize(level: number, tileSize?: number): number;
|
|
163
|
+
/**
|
|
164
|
+
* Tiles of `level` that meet `rect`, clipped to `bounds` (none past the data), ordered from the
|
|
165
|
+
* rectangle's centre outward so the middle of the screen fills first. At most `limit`.
|
|
166
|
+
*/
|
|
167
|
+
export declare function regionTilesInRect(rect: Bbox, level: number, tileSize: number, bounds: Bbox | null, limit?: number): RegionTileKey[];
|
|
168
|
+
/** `level/gx/gy`, a tile's id within one plane. */
|
|
169
|
+
export declare function regionTileId(k: RegionTileKey): string;
|
|
170
|
+
/** The tile of `level` holding image point (x, y). */
|
|
171
|
+
export declare function tileAt(x: number, y: number, level: number, tileSize?: number): RegionTileKey;
|
|
172
|
+
/** True when two boxes meet (edges included). */
|
|
173
|
+
export declare function bboxesMeet(a: Readonly<Bbox>, b: Readonly<Bbox>): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* The feature under image point (x, y): inside an area (even-odd over its rings, so holes are
|
|
176
|
+
* outside) or within `tolerance` image pixels of a polyline. Of several, the one with the
|
|
177
|
+
* smallest box — the innermost of nested outlines. Null when none is.
|
|
178
|
+
*/
|
|
179
|
+
export declare function featureAt(features: Iterable<TileFeature>, x: number, y: number, tolerance?: number): TileFeature | null;
|
|
180
|
+
/** Features whose box meets `rect` (the rubber band's rule for regions). */
|
|
181
|
+
export declare function featuresInRect(features: Iterable<TileFeature>, rect: Readonly<Bbox>): TileFeature[];
|
|
182
|
+
/** Even-odd containment over interleaved rings. */
|
|
183
|
+
export declare function insideRings(rings: readonly ArrayLike<number>[], x: number, y: number): boolean;
|
|
184
|
+
/** Douglas–Peucker over an open polyline (both ends kept). */
|
|
185
|
+
export declare function simplifyPolyline(xs: number[], ys: number[], epsilon: number): {
|
|
186
|
+
xs: number[];
|
|
187
|
+
ys: number[];
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Rings simplified for a level: every ring through Douglas–Peucker at the level's tolerance,
|
|
191
|
+
* rings whose box is under the level's minimum extent dropped, and rings left with too few
|
|
192
|
+
* vertices to draw (3 for a closed ring, 2 for a polyline) dropped. Level 0 returns the rings
|
|
193
|
+
* as they are.
|
|
194
|
+
*/
|
|
195
|
+
export declare function simplifyRings(rings: readonly Float64Array[], open: boolean, level: number): Float32Array[];
|
|
196
|
+
/**
|
|
197
|
+
* A parsed GeoJSON region set, indexed for tiles. Holds the raw features (for the exact
|
|
198
|
+
* geometry and the export), each feature's rings, box, plane and class, and builds a level's
|
|
199
|
+
* tile buckets the first time that level of a plane is asked for.
|
|
200
|
+
*/
|
|
201
|
+
export declare class RegionFeatureTable {
|
|
202
|
+
readonly raw: GeoJsonFeatureLike[];
|
|
203
|
+
readonly tileSize: number;
|
|
204
|
+
readonly ids: string[];
|
|
205
|
+
readonly labels: Array<string | null>;
|
|
206
|
+
readonly colors: Array<string | null>;
|
|
207
|
+
readonly planes: number[];
|
|
208
|
+
readonly boxes: Bbox[];
|
|
209
|
+
readonly rings: Float64Array[][];
|
|
210
|
+
readonly open: boolean[];
|
|
211
|
+
/** Per feature, its parts as ring indices (the exterior first, then its holes). */
|
|
212
|
+
readonly parts: number[][][];
|
|
213
|
+
private readonly labelPoints;
|
|
214
|
+
/** Each feature's area, worked out the first time its row is asked for. */
|
|
215
|
+
private readonly areas;
|
|
216
|
+
private hierarchy?;
|
|
217
|
+
private style?;
|
|
218
|
+
private readonly byId;
|
|
219
|
+
private readonly buckets;
|
|
220
|
+
private readonly simplified;
|
|
221
|
+
private readonly bounds;
|
|
222
|
+
private readonly levels;
|
|
223
|
+
constructor(raw: GeoJsonFeatureLike[], tileSize?: number);
|
|
224
|
+
/** Parse a GeoJSON FeatureCollection string. Throws on invalid JSON or no `features`. */
|
|
225
|
+
static fromGeoJson(text: string, tileSize?: number): RegionFeatureTable;
|
|
226
|
+
/** Attach a class hierarchy and a style hint (each ignored when not well formed). */
|
|
227
|
+
describe(hierarchy?: unknown, style?: unknown): void;
|
|
228
|
+
/**
|
|
229
|
+
* The outlines of every feature of these classes, plane by plane, simplified for `level` (what a
|
|
230
|
+
* 3D reconstruction of the classes stacks), without the `exclude`d ids: closed features' rings,
|
|
231
|
+
* open features' polylines as `lines`, each ring with its feature (`ringGroups`). Planes without
|
|
232
|
+
* one are left out. `classes` null reads every labelled feature, each outline with its class
|
|
233
|
+
* (`ringLabels`, `lineLabels`).
|
|
234
|
+
*/
|
|
235
|
+
classOutlines(classes: readonly string[] | null, level: number, exclude?: readonly string[]): ClassOutlines[];
|
|
236
|
+
/** Features per class on plane `z` (null: on every plane), without the `exclude`d ids. */
|
|
237
|
+
classCounts(z: number | null, exclude?: readonly string[]): Record<string, number>;
|
|
238
|
+
info(): RegionSourceInfo;
|
|
239
|
+
/** One tile of plane `z`. */
|
|
240
|
+
tile(z: number, level: number, gx: number, gy: number): RegionTile;
|
|
241
|
+
/** The raw GeoJSON features with these ids, in the order asked (unknown ids skipped). */
|
|
242
|
+
features(ids: readonly string[]): Array<{
|
|
243
|
+
id: string;
|
|
244
|
+
feature: GeoJsonFeatureLike;
|
|
245
|
+
}>;
|
|
246
|
+
/** Feature `i`'s area in px² (0 for a polyline). */
|
|
247
|
+
private areaOf;
|
|
248
|
+
/** A page of plane `z`'s features, in file order. */
|
|
249
|
+
index(z: number, query: RegionIndexQuery): RegionIndexPage;
|
|
250
|
+
/**
|
|
251
|
+
* The source as a GeoJSON FeatureCollection string, through the working set: features whose
|
|
252
|
+
* id is in `exclude` (taken for editing, or deleted) are left out, `extra` (the working set's
|
|
253
|
+
* features) appended. Every feature keeps an `id`; the set keeps its hierarchy and style.
|
|
254
|
+
*/
|
|
255
|
+
exportGeoJson(exclude: readonly string[], extra: readonly object[]): string;
|
|
256
|
+
/**
|
|
257
|
+
* Feature `i`'s label points (one per part with room for a label at `level`: a part under the
|
|
258
|
+
* level's minimum extent is not drawn there), from the exact geometry, computed once.
|
|
259
|
+
*/
|
|
260
|
+
private labelsAt;
|
|
261
|
+
/** Feature `i`'s rings at `level`, simplified once and cached. */
|
|
262
|
+
private ringsAt;
|
|
263
|
+
/** Entries in plane `z`'s level-`level` index: cell listings plus wide features (tests). */
|
|
264
|
+
indexEntries(z: number, level: number): number;
|
|
265
|
+
/**
|
|
266
|
+
* Plane `z`'s level-`level` index, built on first use: features by tile cell (`gx/gy` → feature
|
|
267
|
+
* indices), and the wide ones (more than {@link MAX_CELLS_PER_FEATURE} cells, or past the
|
|
268
|
+
* number range), tested against a tile when it is asked for.
|
|
269
|
+
*/
|
|
270
|
+
private bucketsFor;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* A feature spanning more tiles than this is not listed in each of them but kept aside and tested
|
|
274
|
+
* against a tile when one is asked for: one huge box (an outline around a whole slide, or a corrupt
|
|
275
|
+
* coordinate) must not make a plane's index millions of entries.
|
|
276
|
+
*/
|
|
277
|
+
export declare const MAX_CELLS_PER_FEATURE = 64;
|
|
278
|
+
/** A feature's own id (`id`, else `properties.id`) as a string. */
|
|
279
|
+
export declare function featureIdOf(feature: GeoJsonFeatureLike): string | undefined;
|
|
280
|
+
/**
|
|
281
|
+
* A FeatureCollection string of `features` (each a feature's JSON), with the set's class hierarchy
|
|
282
|
+
* and style as its `classHierarchy` and `style` members when it has them: what
|
|
283
|
+
* {@link RegionFeatureTable.fromGeoJson} reads back.
|
|
284
|
+
*/
|
|
285
|
+
export declare function featureCollectionJson(features: readonly string[], hierarchy?: readonly RegionClassNode[], style?: RegionSourceStyle): string;
|
|
286
|
+
/** A well-formed class hierarchy from a file (colours as `#rrggbb` or `[r, g, b]`), else undefined. */
|
|
287
|
+
export declare function readHierarchy(raw: unknown): RegionClassNode[] | undefined;
|
|
288
|
+
/** A well-formed style hint from a file, else undefined. */
|
|
289
|
+
export declare function readStyle(raw: unknown): RegionSourceStyle | undefined;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A {@link RegionSource} over a GeoJSON string, parsed and tiled in the region-source Web Worker.
|
|
3
|
+
*
|
|
4
|
+
* One worker serves every open source. Where no worker can start (jsdom, SSR, a blocked worker
|
|
5
|
+
* URL) the same tables run on the main thread; if the worker dies, each source re-opens itself
|
|
6
|
+
* there from its text (which the host holds anyway: it handed it over) and carries on — whether
|
|
7
|
+
* it had a call in flight then or not (see {@link RegionSourceWorkerClient.generation}).
|
|
8
|
+
*/
|
|
9
|
+
import { RegionSource } from './region-source';
|
|
10
|
+
import { RegionSourceRequest, RegionSourceResults } from './region-source-ops';
|
|
11
|
+
import type { ReconstructOptions, SliceOutlines } from '../geometry/reconstruct';
|
|
12
|
+
import type { Mesh } from 'napari-js/geometry';
|
|
13
|
+
/** Makes the worker; may be async, as the default one is (it imports the factory on demand). */
|
|
14
|
+
export type RegionSourceWorkerFactory = () => Worker | Promise<Worker>;
|
|
15
|
+
/** Owns the region-source worker and the calls in flight on it. */
|
|
16
|
+
export declare class RegionSourceWorkerClient {
|
|
17
|
+
private readonly factory?;
|
|
18
|
+
private worker;
|
|
19
|
+
private starting;
|
|
20
|
+
private unavailable;
|
|
21
|
+
private nextId;
|
|
22
|
+
private readonly pending;
|
|
23
|
+
/** The main-thread tables, once anything runs here. */
|
|
24
|
+
private local;
|
|
25
|
+
private tables;
|
|
26
|
+
/**
|
|
27
|
+
* `factory` is optional: without one the real worker module is imported on demand —
|
|
28
|
+
* dynamically, because it holds an `import.meta.url` that ts-jest's CommonJS compile
|
|
29
|
+
* rejects.
|
|
30
|
+
*/
|
|
31
|
+
constructor(factory?: RegionSourceWorkerFactory | undefined);
|
|
32
|
+
/** Whether calls now run on the main thread. */
|
|
33
|
+
get inThread(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Which table set calls run on: bumped when the worker is lost. A handle opened under another
|
|
36
|
+
* names a table that is gone (or, here, another source's), so its source must open again.
|
|
37
|
+
*/
|
|
38
|
+
get generation(): number;
|
|
39
|
+
/** Run `request` in the worker, or here when there is none. */
|
|
40
|
+
call<R extends RegionSourceRequest>(request: R): Promise<RegionSourceResults[R['op']]>;
|
|
41
|
+
/** {@link call}, with the {@link generation} the request ran on. */
|
|
42
|
+
run<R extends RegionSourceRequest>(request: R): Promise<{
|
|
43
|
+
result: RegionSourceResults[R['op']];
|
|
44
|
+
generation: number;
|
|
45
|
+
}>;
|
|
46
|
+
/** Terminate the worker; calls in flight reject. */
|
|
47
|
+
dispose(): void;
|
|
48
|
+
private ensureWorker;
|
|
49
|
+
private startWorker;
|
|
50
|
+
private onReply;
|
|
51
|
+
/** Stop the worker for good: every later call runs here, every call in flight is lost. */
|
|
52
|
+
private lose;
|
|
53
|
+
}
|
|
54
|
+
/** The worker client every GeoJSON source shares. */
|
|
55
|
+
export declare function sharedRegionSourceClient(): RegionSourceWorkerClient;
|
|
56
|
+
/**
|
|
57
|
+
* Open a GeoJSON FeatureCollection string as a tiled region source. Rejects on invalid JSON or
|
|
58
|
+
* a collection without `features`.
|
|
59
|
+
*/
|
|
60
|
+
export declare function openGeoJsonRegionSource(text: string, client?: RegionSourceWorkerClient): Promise<RegionSource>;
|
|
61
|
+
/**
|
|
62
|
+
* The 3D reconstruction of a region from its outlines on a stack (see `geometry/reconstruct`),
|
|
63
|
+
* meshed in the region-source worker (on the main thread where there is none).
|
|
64
|
+
*/
|
|
65
|
+
export declare function reconstructInWorker(slices: readonly SliceOutlines[], options?: ReconstructOptions, client?: RegionSourceWorkerClient): Promise<Mesh>;
|
|
@@ -11,6 +11,10 @@ import { IVisualizer, LoadedImage, PixelData, IntensityProfile, IIsosurfaceContr
|
|
|
11
11
|
import { SpatialDataPort } from './contracts/ports/spatial-data.port';
|
|
12
12
|
import { CanvasToolOptions, ColormapNode, IBrushOptions, IWandOptions } from './contracts/display-types';
|
|
13
13
|
import { RegionStore } from './store/region-store.service';
|
|
14
|
+
import { RegionSource, RegionSourceView } from './region-source/region-source';
|
|
15
|
+
import type { RegionIndexPage, RegionIndexQuery } from './region-source/region-tiles';
|
|
16
|
+
import type { RegionStyle } from './region-overlay/region-style';
|
|
17
|
+
import type { RegionSourceOpener, RegionSourceSlices } from './store/region-source-scope';
|
|
14
18
|
import { SpatialSelectionStore } from './store/spatial-selection.service';
|
|
15
19
|
import { ViewerCapabilities } from './contracts/capabilities.contract';
|
|
16
20
|
import { IRegionOverlay } from './contracts/region-overlay.contract';
|
|
@@ -21,7 +25,10 @@ import { NapariVisualizerService } from './implementations/napari-js/napari-visu
|
|
|
21
25
|
import { VizConfig } from './contracts/viz-config';
|
|
22
26
|
import { PlotModeViewport } from './contracts/plot-type-contribution.contract';
|
|
23
27
|
import { IntensityProfileService } from './intensity/intensity-profile.service';
|
|
28
|
+
import type { SectionAxis, SectionViews } from './contracts/section-view.contract';
|
|
24
29
|
import * as i0 from "@angular/core";
|
|
30
|
+
/** How long after the last edit the surfaces of the classes it touched are rebuilt (ms). */
|
|
31
|
+
export declare const REGION_SURFACE_REBUILD_MS = 600;
|
|
25
32
|
/**
|
|
26
33
|
* The visualizer chain's front door: implements `IVisualizer`, `IRegionEditorApi`
|
|
27
34
|
* and `IChannelHistogramApi` (bound to the `VISUALIZER` / `REGION_EDITOR_API` /
|
|
@@ -68,7 +75,55 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
68
75
|
private plottedFileName;
|
|
69
76
|
/** The div the backends render into (every backend shares it); '' before the first plot. */
|
|
70
77
|
private plotDiv;
|
|
78
|
+
/** Whether a napari volume view is the current plot type. */
|
|
79
|
+
private readonly volumeView$;
|
|
80
|
+
/** Whether the volume view's slice pane is wanted (see {@link setSliceEditor}). */
|
|
81
|
+
private readonly sliceEditor$;
|
|
82
|
+
/** Whether the volume view draws the region reconstructions through the volume. */
|
|
83
|
+
private readonly regionsThroughVolume$;
|
|
84
|
+
/** Region reconstructions built so far, by image, resolution and classes (with those classes). */
|
|
85
|
+
private readonly meshCache;
|
|
86
|
+
/** Bumped per {@link showRegionClasses3d} (and per new image), so only the latest one shows. */
|
|
87
|
+
private meshRequest;
|
|
88
|
+
/** The class groups shown in 3D, and the image they belong to. */
|
|
89
|
+
private readonly classes3d$;
|
|
90
|
+
private classes3dImage;
|
|
91
|
+
/** The groups last asked for in 3D, with their colours: what an edit's rebuild shows again. */
|
|
92
|
+
private shown3d;
|
|
93
|
+
/**
|
|
94
|
+
* Each class's fingerprint on the live slice (see classSignatures), which image and slice, and
|
|
95
|
+
* what the region sources hold (see RegionStore.getSourceStateKey). Null while nothing follows
|
|
96
|
+
* the edits (no surface built, no sections).
|
|
97
|
+
*/
|
|
98
|
+
private liveClasses;
|
|
99
|
+
/** The pending rebuild of the surfaces an edit touched. */
|
|
100
|
+
private rebuildTimer;
|
|
101
|
+
private readonly regionUpdates;
|
|
102
|
+
/** The div the slice pane renders into while it is wanted (null: no split). */
|
|
103
|
+
private sliceDiv;
|
|
104
|
+
/** Whether OSD is mounted in the slice pane: region, tool and overlay calls go to it. */
|
|
105
|
+
private sliceMounted;
|
|
106
|
+
/** The image the slice pane shows. */
|
|
107
|
+
private sliceFile;
|
|
108
|
+
/** Bumped per slice-pane mount or teardown, so only the latest one lands. */
|
|
109
|
+
private sliceRequest;
|
|
110
|
+
/** The sections beside the split volume view (the planes x and y through the stack). */
|
|
111
|
+
private readonly sections;
|
|
112
|
+
/** The z plane dragged in the volume: the slice to show (see {@link getSliceDrag$}). */
|
|
113
|
+
private readonly sliceDrag$;
|
|
114
|
+
private readonly sectionSubs;
|
|
115
|
+
/** The image info and screen height of the last plot (what the slice pane mounts). */
|
|
116
|
+
private plottedInfo;
|
|
117
|
+
private plottedHeight;
|
|
71
118
|
constructor(plotly: PlotlyService, osd: OpenSeadragonVisualizerService, napari: NapariVisualizerService, store: VisualizerStore, config: VizConfig, regionStore: RegionStore, selectionStore: SpatialSelectionStore, intensity: IntensityProfileService, spatialData?: SpatialDataPort | null);
|
|
119
|
+
/** A class's colour: its classification colour, else its region source's, else a default. */
|
|
120
|
+
private classColor;
|
|
121
|
+
/** The sections beside the split volume view (nulls while it is not split). */
|
|
122
|
+
getSectionViews$(): Observable<SectionViews>;
|
|
123
|
+
/** Move a section's plane to `at` (image px). */
|
|
124
|
+
setSectionPlane(axis: SectionAxis, at: number): void;
|
|
125
|
+
/** The slice picked by dragging the z plane in the volume: the host shows it (its slider). */
|
|
126
|
+
getSliceDrag$(): Observable<number>;
|
|
72
127
|
private isImageType;
|
|
73
128
|
/** The 2D napari types (image, region-centroid scatter, spatial omics) — a 2D fallback chain
|
|
74
129
|
* (OSD, then Plotly).
|
|
@@ -92,11 +147,27 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
92
147
|
private imageBackend;
|
|
93
148
|
/** Backend currently on screen — what ongoing zoom/tool/region ops act on. */
|
|
94
149
|
private renderer;
|
|
150
|
+
/**
|
|
151
|
+
* Backend region, tool and overlay calls act on: the slice pane's OSD while the volume view is
|
|
152
|
+
* split (regions are edited there), else the backend on screen. View calls (zoom, fit, colour,
|
|
153
|
+
* export) stay with {@link renderer}.
|
|
154
|
+
*/
|
|
155
|
+
private regionBackend;
|
|
95
156
|
get capabilities(): ViewerCapabilities;
|
|
96
157
|
load(imageInfo: IImageInfo, zIndex: number, signal?: AbortSignal): Promise<LoadedImage>;
|
|
97
158
|
/** Try OSD; on failure fall back to Plotly for this image (not permanent — see reset()). */
|
|
98
159
|
private loadViaOsdThenPlotly;
|
|
99
160
|
plot(plotDiv: string, imageLoaded: unknown, imageInfo: IImageInfo, screenHeight: number, plotType: PlotType, inPlace?: boolean): Promise<boolean>;
|
|
161
|
+
/**
|
|
162
|
+
* Split the volume view: show the slice being edited in `div` (OpenSeadragon, with every region
|
|
163
|
+
* tool) beside the 3D view, or stop (null). Kept across re-plots of a volume view; another plot
|
|
164
|
+
* type takes the pane down and a volume view brings it back. Resolves whether the pane shows.
|
|
165
|
+
*/
|
|
166
|
+
setSliceEditor(div: string | null): Promise<boolean>;
|
|
167
|
+
/** Mount (or refresh in place) OSD in the slice pane on the displayed slice. */
|
|
168
|
+
private mountSlice;
|
|
169
|
+
/** Take the slice pane's viewer down (the split stays wanted while {@link sliceDiv} is set). */
|
|
170
|
+
private unmountSlice;
|
|
100
171
|
reloadAndPlot(): void;
|
|
101
172
|
reset(): void;
|
|
102
173
|
relayout(trueImageSize?: number[]): void;
|
|
@@ -190,9 +261,74 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
190
261
|
/** Download `regions` as GeoJSON, named after the image last plotted. */
|
|
191
262
|
exportRegions(regions: Region[]): void;
|
|
192
263
|
getGeoJsonString(regions: Region[]): string;
|
|
264
|
+
/** Hold a large region set as a tiled region source (see RegionStore.attachRegionSource). */
|
|
265
|
+
attachRegionSource(source: RegionSource | RegionSourceOpener, slices?: RegionSourceSlices): void;
|
|
266
|
+
importRegionSource(geoJsonStr: string): Promise<boolean>;
|
|
267
|
+
dropRegionSource(): Promise<void>;
|
|
268
|
+
getRegionSourceView$(): Observable<RegionSourceView | null>;
|
|
269
|
+
getRegionSourceIndex(query: Omit<RegionIndexQuery, 'exclude'>): Promise<RegionIndexPage>;
|
|
270
|
+
selectSourceFeatures(ids: readonly string[], additive?: boolean): Promise<number[]>;
|
|
271
|
+
deleteSourceFeatures(ids: readonly string[]): void;
|
|
272
|
+
getRegionStyle$(): Observable<RegionStyle>;
|
|
273
|
+
setRegionStyle(patch: Partial<RegionStyle>): void;
|
|
274
|
+
/** Whether a napari volume (or isosurface) view is on screen: regions can be shown in 3D. */
|
|
275
|
+
getVolumeView$(): Observable<boolean>;
|
|
276
|
+
/** Whether the volume view's slice pane is wanted (it shows while a volume view is on screen). */
|
|
277
|
+
getSliceEditor$(): Observable<boolean>;
|
|
278
|
+
/** Whether the volume view draws the region reconstructions through the volume. */
|
|
279
|
+
getRegionsThroughVolume$(): Observable<boolean>;
|
|
280
|
+
/**
|
|
281
|
+
* Draw the region reconstructions through the volume (it hides none of them: surfaces inside its
|
|
282
|
+
* bright structures, an OCT's layer boundaries) or hidden behind what it shows (the default).
|
|
283
|
+
*/
|
|
284
|
+
setRegionsThroughVolume(through: boolean): void;
|
|
285
|
+
/** The class groups shown in 3D on this image ([] after a switch to another image). */
|
|
286
|
+
getRegionClasses3d$(): Observable<ReadonlyArray<{
|
|
287
|
+
key: string;
|
|
288
|
+
classes: readonly string[];
|
|
289
|
+
}>>;
|
|
290
|
+
/** Hide every region surface and forget them (a build still running is dropped). */
|
|
291
|
+
private clearRegionClasses3d;
|
|
292
|
+
/** Highlight the surfaces of these group keys in the volume view (none: all as usual). */
|
|
293
|
+
highlightRegionClasses3d(keys: readonly string[]): void;
|
|
294
|
+
/** A surface clicked in the volume view with the selection tool (its group key), or none (null). */
|
|
295
|
+
getRegionPicked3d$(): Observable<{
|
|
296
|
+
key: string | null;
|
|
297
|
+
additive: boolean;
|
|
298
|
+
}>;
|
|
299
|
+
/**
|
|
300
|
+
* Show these groups of classes in the volume view as 3D reconstructions (each group one surface
|
|
301
|
+
* in its colour: an atlas structure with its substructures), and only these; [] hides them.
|
|
302
|
+
* Reconstructed from every slice's outlines at the volume's resolution, cached per image.
|
|
303
|
+
*/
|
|
304
|
+
showRegionClasses3d(groups: ReadonlyArray<{
|
|
305
|
+
key: string;
|
|
306
|
+
classes: readonly string[];
|
|
307
|
+
color: string;
|
|
308
|
+
label?: string;
|
|
309
|
+
}>): Promise<void>;
|
|
310
|
+
/**
|
|
311
|
+
* The regions changed: when the live slice's regions of some classes did (an edit, an undo, not
|
|
312
|
+
* a slice or image switch), their reconstructions are stale. They are dropped, and those shown
|
|
313
|
+
* in 3D are rebuilt once the edits pause.
|
|
314
|
+
*/
|
|
315
|
+
private onRegionsChanged;
|
|
316
|
+
/** Fingerprint the live slice's classes, unless already: what the next edit is compared with. */
|
|
317
|
+
private trackLiveClasses;
|
|
318
|
+
/** Which slice of which image the live regions are. */
|
|
319
|
+
private liveSliceKey;
|
|
320
|
+
/** Each class's volume over the whole stack, in px² × slices (see RegionStore.classVolumes). */
|
|
321
|
+
getClassVolumes(classes: readonly string[]): Promise<Record<string, number>>;
|
|
322
|
+
getRegionSourceClassCounts(stack?: boolean): Promise<Record<string, number>>;
|
|
323
|
+
getHiddenClasses$(): Observable<ReadonlySet<string>>;
|
|
324
|
+
setClassesHidden(classes: readonly string[], hidden: boolean): void;
|
|
325
|
+
selectRegionClasses(classes: readonly string[], additive?: boolean): Promise<void>;
|
|
326
|
+
getGeoJsonStringWithSource(regions: Region[], slice?: number): Promise<string>;
|
|
193
327
|
enterStackMode(slices: Map<number, Region[]>, initialZ?: number, saveLayout?: 'combined' | 'per-slice-file'): void;
|
|
194
328
|
exitStackMode(): void;
|
|
195
329
|
isStackMode(): boolean;
|
|
330
|
+
/** The slice the regions are shown for (recorded outside stack mode too). */
|
|
331
|
+
getDisplaySlice(): number;
|
|
196
332
|
getStackSaveLayout(): 'combined' | 'per-slice-file';
|
|
197
333
|
setDisplaySlice(z: number): void;
|
|
198
334
|
getSliceRegions(): Region[];
|
|
@@ -261,7 +397,8 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
261
397
|
getInvert$(): Observable<boolean>;
|
|
262
398
|
setInvert(on: boolean): void;
|
|
263
399
|
/**
|
|
264
|
-
* The active backend's region overlay
|
|
400
|
+
* The active backend's region overlay (the slice pane's while the volume view is split). Falls
|
|
401
|
+
* back to Plotly's when the active backend
|
|
265
402
|
* (OSD or napari-js) is selected but a plot isn't mounted yet, so callers always get a
|
|
266
403
|
* usable overlay.
|
|
267
404
|
*/
|