Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
633a442
feat(lib): detect the grid type from the zarr dggs convention
keewis Jun 5, 2026
2cf5790
fix(lib): fixed EPSG3857 if spatial_ref is a coordinate
Karinon Jun 9, 2026
5ceed6d
fix(lib): better dataset recognition for Curvilinear and Regular Data…
Karinon Jun 9, 2026
b1efc23
chore(lib): get dimensions in parallel
Karinon Jun 9, 2026
3bb62ac
chore(ui): Control-Panel is no longer open when loading a new dataset…
Karinon Jun 9, 2026
eb7740b
chore: typing of the dggs metadata
keewis Jun 9, 2026
f2beefd
chore(lib): removed all the Float64 conversion
Karinon Jun 10, 2026
2f0a943
chore: Float64 to Float32
Karinon Jun 10, 2026
5906951
chore: split `getGridType`
keewis Jun 10, 2026
9b7e85d
refactor: use an array of functions
keewis Jun 10, 2026
cd2b979
Merge pull request #179 from keewis/dggs-convention
Karinon Jun 10, 2026
524d62a
fix(lib): fixed EPSG3857 if spatial_ref is a coordinate
Karinon Jun 9, 2026
43b5708
fix(lib): better dataset recognition for Curvilinear and Regular Data…
Karinon Jun 9, 2026
d3d8c3e
chore(lib): get dimensions in parallel
Karinon Jun 9, 2026
f981848
chore(ui): Control-Panel is no longer open when loading a new dataset…
Karinon Jun 9, 2026
3363a95
chore(lib): removed all the Float64 conversion
Karinon Jun 10, 2026
9803704
chore: Float64 to Float32
Karinon Jun 10, 2026
54388c1
chore: update deps
Karinon Jun 10, 2026
71597a5
Merge branch 'fix/epsg3857' of https://github.com/d70-t/gridlook into…
Karinon Jun 10, 2026
aaedfe4
chore: fix rebase issue
Karinon Jun 10, 2026
a80ce46
chore: fix package-lon.json
Karinon Jun 10, 2026
e062aad
chore: updated default node-version
Karinon Jun 10, 2026
e9002a1
feat: added hide high button
Karinon Jun 12, 2026
511b192
feat: support for icechunk-groups as datasets
Karinon Jun 12, 2026
45a7ab8
feat: support for pcodec
Karinon Jun 12, 2026
afaad69
chore: added unit tests for grid type detection
Karinon Jun 15, 2026
68ff001
chore: added unit tests to the workflow
Karinon Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ jobs:
- name: Run type checker
run: npm run typecheck

- name: Run unit tests
run: npm run test

- name: Test-Build
run: npm run build
1,601 changes: 974 additions & 627 deletions package-lock.json

Large diffs are not rendered by default.

49 changes: 27 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
"dev": "vite --port 3000",
"build": "vue-tsc -b && vite build",
"preview": "vite preview --port 5050",
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "vue-tsc --noEmit",
"lint": "eslint src",
"lint-ci": "eslint src --max-warnings 0",
"lint:fix": "eslint src --fix",
"lint": "eslint src tests",
"lint-ci": "eslint src tests --max-warnings 0",
"lint:fix": "eslint src tests --fix",
"prepare": "husky"
},
"lint-staged": {
Expand All @@ -26,70 +28,73 @@
},
"type": "module",
"dependencies": {
"@eeholmes/zarrita-pcodec": "github:eeholmes/zarrita-pcodec",
"@fortawesome/fontawesome-free": "^7.2.0",
"@hscmap/healpix": "^1.4.12",
"@primevue/themes": "^4.5.4",
"@vuepic/vue-datepicker": "13.0.0",
"@vueuse/core": "^14.2.1",
"axios": "^1.15.2",
"@vuepic/vue-datepicker": "14.0.0",
"@vueuse/core": "^14.3.0",
"axios": "^1.18.0",
"bulma": "^1.0.4",
"canvas-txt": "^4.1.1",
"chart.js": "^4.5.1",
"chartjs-plugin-annotation": "^3.1.0",
"d3-delaunay": "^6.0.4",
"d3-geo": "^3.1.1",
"d3-geo-projection": "^4.0.0",
"dayjs": "^1.11.20",
"dayjs": "^1.11.21",
"fflate": "^0.8.3",
"geokdbush": "2.1.0",
"humanize-duration": "^3.33.2",
"icechunk-js": "^0.4.0",
"kdbush": "4.0.2",
"kdbush": "4.1.0",
"pinia": "^3.0.4",
"primevue": "^4.5.5",
"proj4": "^2.20.9",
"qrcode": "^1.5.4",
"quick-lru": "^7.3.0",
"three": "^0.184",
"three-conic-polygon-geometry": "^2.1.3",
"three-geojson-geometry": "^2.1.1",
"vue": "^3.5.33",
"vue": "^3.5.38",
"vue-json-pretty": "^2.6.0",
"vue-router": "^5.0.6",
"vue-router": "^5.1.0",
"zarrita": "^0.7.3"
},
"devDependencies": {
"@commitlint/cli": "^20.5.0",
"@commitlint/config-conventional": "^20.5.0",
"@commitlint/cli": "^21.0.2",
"@commitlint/config-conventional": "^21.0.2",
"@types/d3-delaunay": "^6.0.4",
"@types/d3-geo": "^3.1.0",
"@types/geojson": "7946.0.16",
"@types/humanize-duration": "^3.27.4",
"@types/node": "^20.17",
"@types/node": "~24",
"@types/qrcode": "^1.5.6",
"@types/three": "0.184.1",
"@vitejs/plugin-vue": "^6.0.6",
"@vitejs/plugin-vue": "^6.0.7",
"@vue/tsconfig": "0.9.1",
"eslint": "^9.39.4",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-boundaries": "^6.0.2",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-prettier": "^5.5.5",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-vue": "10.8",
"globals": "^17.5.0",
"eslint-plugin-prettier": "^5.5.6",
"eslint-plugin-promise": "^7.3.0",
"eslint-plugin-vue": "10.9",
"globals": "^17.6.0",
"glslify": "^7.1.1",
"husky": "^9.1.7",
"lint-staged": "^16.4.0",
"prettier": "^3.8.3",
"lint-staged": "^17.0.7",
"prettier": "^3.8.4",
"sass": "~1.89.2",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.0",
"vite": "^8.0.10",
"vite-plugin-glsl": "^1.6.0",
"vitest": "^4.1.9",
"vue-tsc": "^3.2.7"
},
"engines": {
"node": ">=20.17.0"
"node": ">=24.16.0"
}
}
77 changes: 51 additions & 26 deletions src/lib/data/ZarrDataManager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { IcechunkStore } from "icechunk-js";
import QuickLRU from "quick-lru";
import * as zarr from "zarrita";

import {
createIcechunkStore,
isIcechunkStorePath,
parseStorePath,
} from "./icechunkStore.ts";

import {
ZARR_FORMAT,
type TDataSource,
Expand All @@ -26,7 +31,6 @@ export type TZarrVariableMetadata = {
};

type TDatasetSource = Pick<TDataSource, "dataset" | "store">;
type TIcechunkStore = zarr.AsyncReadable & Pick<IcechunkStore, "listNodes">;

export class ZarrDataManager {
private static pendingStore: Promise<
Expand All @@ -42,33 +46,17 @@ export class ZarrDataManager {
return dataset.replace(/^\/+/, "").replace(/\/+$/, "");
}

static isIcechunkStorePath(storePath: string) {
return this.normalizeStorePath(storePath.split(/[?#]/)[0]).endsWith(
".icechunk"
);
}

private static async createIcechunkStore(
storePath: string
): Promise<TIcechunkStore> {
return await IcechunkStore.open(this.normalizeStorePath(storePath));
}

static async createListableIcechunkStore(storePath: string) {
const store = await this.createIcechunkStore(storePath);
const contents = store.listNodes().map((node) => ({
path: node.path as zarr.AbsolutePath,
kind: node.nodeData.type,
}));
return Object.assign(store, { contents: () => contents });
}

public static async createNewStore(storePath: string, isIcechunk = false) {
const parsed = parseStorePath(storePath);
let store: zarr.AsyncReadable | undefined = undefined;
if (isIcechunk || this.isIcechunkStorePath(storePath)) {
store = await this.createIcechunkStore(storePath);
if (
isIcechunk ||
parsed.backend === "icechunk" ||
isIcechunkStorePath(storePath)
) {
store = await createIcechunkStore(storePath);
} else {
store = new zarr.FetchStore(storePath, { useSuffixRequest: true });
store = new zarr.FetchStore(parsed.url, { useSuffixRequest: true });
}

const cache = new QuickLRU<string, Uint8Array | undefined>({
Expand Down Expand Up @@ -150,6 +138,28 @@ export class ZarrDataManager {
return array;
}

static async getParentGroup(
datasources: TSources,
varname: string,
format?: TZarrFormat
): Promise<zarr.Group<zarr.AsyncReadable>> {
const groupPath = await ZarrDataManager.resolveGroupPath(varname);
const source = ZarrDataManager.getDatasetSource(datasources, varname);
const target = (await ZarrDataManager.getDataset(source)).resolve(
groupPath
);

let dataset: zarr.Group<zarr.AsyncReadable>;
if (format === ZARR_FORMAT.V2) {
dataset = await zarr.open.v2(target, { kind: "group" });
} else if (format === ZARR_FORMAT.V3) {
dataset = await zarr.open.v3(target, { kind: "group" });
} else {
dataset = await zarr.open(target, { kind: "group" });
}
return dataset;
}

static async getVariableInfoByDatasetSources(
datasource: TSources,
variable: string
Expand Down Expand Up @@ -211,6 +221,13 @@ export class ZarrDataManager {
if (group.attrs?.grid_mapping) {
return String(group.attrs.grid_mapping).split(":")[0];
}
if (
(datavar.attrs?.coordinates as string | undefined)?.includes(
"spatial_ref"
)
) {
return "spatial_ref";
}
return "crs";
}

Expand All @@ -235,6 +252,14 @@ export class ZarrDataManager {
return datavar.dimensionNames ?? [];
}

static resolveGroupPath(variable: string): string {
if (!variable.includes("/")) {
return "/";
}

return variable.split("/").slice(0, -1).join("/");
}

static resolveVariablePath(
contextVariable: string,
variable: string
Expand Down
3 changes: 2 additions & 1 deletion src/lib/data/codecs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { registerPCodec } from "@eeholmes/zarrita-pcodec";
import { registry } from "zarrita";

import { Fletcher32Codec } from "./fletcher32.ts";

registry.set("numcodecs.fletcher32", async () => Fletcher32Codec);
registerPCodec(registry);
Loading
Loading