@cytario/web 2.2.4 → 2.2.5

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.
@@ -1,30 +1,42 @@
1
- import { AccessorContext } from "@deck.gl/core";
1
+ import { type AccessorContext, type Position } from "@deck.gl/core";
2
2
  import { parseSync } from "@loaders.gl/core";
3
3
  import { WKBLoader } from "@loaders.gl/wkt";
4
4
  import { type Table } from "apache-arrow";
5
+ import { type Geometry } from "geojson";
6
+
7
+ // Dedup per-row warnings — accessor fires per row per frame.
8
+ const warned = new Set<string>();
9
+ const warnOnce = (key: string, level: "warn" | "error", ...args: unknown[]) => {
10
+ if (warned.has(key)) return;
11
+ warned.add(key);
12
+ console[level](...args);
13
+ };
5
14
 
6
15
  export const getPolygon = (arrowTable: Table) => {
7
- // Polygon mode - parse WKB geometry and use SolidPolygonLayer
8
16
  const geomCol = arrowTable.getChild("geom")!;
9
17
 
10
- return (_d: unknown, { index }: AccessorContext<unknown>) => {
11
- // Parse WKB binary geometry
18
+ return (_d: unknown, { index }: AccessorContext<unknown>): Position[][] => {
12
19
  const wkbBuffer = geomCol.get(index);
13
- const geometry = parseSync(wkbBuffer, WKBLoader);
14
-
15
- // Type guard: check if it's a BinaryPolygonGeometry
16
- if (!("positions" in geometry)) {
17
- console.error("Unexpected geometry type:", geometry);
20
+ if (!wkbBuffer) {
21
+ warnOnce("empty-geom", "warn", "[getPolygon] empty geom column value");
18
22
  return [[]];
19
23
  }
20
24
 
21
- // Convert flat Float64Array to nested coordinate array
22
- // SolidPolygonLayer expects: [[[x1, y1], [x2, y2], ...]]
23
- const positions = geometry.positions.value;
24
- const coords: [number, number][] = [];
25
- for (let i = 0; i < positions.length; i += 2) {
26
- coords.push([positions[i], positions[i + 1]]);
25
+ const geometry = parseSync(wkbBuffer, WKBLoader) as Geometry;
26
+
27
+ if (geometry.type === "Polygon") {
28
+ return geometry.coordinates as Position[][];
29
+ }
30
+ if (geometry.type === "MultiPolygon") {
31
+ // SolidPolygonLayer one polygon per row — render first, preprocess upstream for full fidelity.
32
+ warnOnce(
33
+ "multipolygon",
34
+ "warn",
35
+ "[getPolygon] MultiPolygon downgraded to first polygon; preprocess to one row per polygon for full rendering",
36
+ );
37
+ return (geometry.coordinates[0] ?? [[]]) as Position[][];
27
38
  }
28
- return [coords]; // Wrap in array for simple polygon
39
+ warnOnce("unknown-type", "error", "[getPolygon] unexpected geometry type:", geometry);
40
+ return [[]];
29
41
  };
30
42
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cytario/web",
3
- "version": "2.2.4",
3
+ "version": "2.2.5",
4
4
  "description": "Cytario Web — scientific imaging data browser and viewer for OME-TIFF, OME-Zarr, Parquet and GeoTIFF on S3-compatible storage.",
5
5
  "license": "AGPL-3.0",
6
6
  "sideEffects": false,
@@ -84,8 +84,8 @@
84
84
  "@duckdb/node-api": "^1.5.0-r.1",
85
85
  "@hms-dbmi/viv": "^0.20.1",
86
86
  "@hookform/resolvers": "^5.2.2",
87
- "@loaders.gl/core": "^4.3.4",
88
- "@loaders.gl/wkt": "^4.3.4",
87
+ "@loaders.gl/core": "4.4.2",
88
+ "@loaders.gl/wkt": "4.4.2",
89
89
  "@prisma/adapter-pg": "^7.5.0",
90
90
  "@prisma/client": "^7.5.0",
91
91
  "@react-router/dev": "^7.13.2",