@faclon-labs/app-sdk 0.1.0 → 0.2.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/README.md +34 -1
- package/dist/SignIn.js +2 -2
- package/dist/config.d.ts +5 -0
- package/dist/config.js +1 -0
- package/dist/map/globe.d.ts +5 -0
- package/dist/map/globe.js +5 -0
- package/dist/map/index.d.ts +21 -0
- package/dist/map/index.js +21 -0
- package/dist/map/source.d.ts +46 -0
- package/dist/map/source.js +54 -0
- package/dist/map/testing.d.ts +5 -0
- package/dist/map/testing.js +5 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +1 -1
- package/package.json +55 -5
- package/vendor/SOURCE.txt +1 -0
- package/vendor/map-engine/cesium/camera.d.ts +10 -0
- package/vendor/map-engine/cesium/camera.js +25 -0
- package/vendor/map-engine/cesium/index.d.ts +2 -0
- package/vendor/map-engine/cesium/index.js +2 -0
- package/vendor/map-engine/cesium/renderer.d.ts +149 -0
- package/vendor/map-engine/cesium/renderer.js +837 -0
- package/vendor/map-engine/commands/index.d.ts +2 -0
- package/vendor/map-engine/commands/index.js +2 -0
- package/vendor/map-engine/commands/post-message.d.ts +32 -0
- package/vendor/map-engine/commands/post-message.js +77 -0
- package/vendor/map-engine/commands/webmcp.d.ts +17 -0
- package/vendor/map-engine/commands/webmcp.js +59 -0
- package/vendor/map-engine/core/commands.d.ts +82 -0
- package/vendor/map-engine/core/commands.js +46 -0
- package/vendor/map-engine/core/emitter.d.ts +9 -0
- package/vendor/map-engine/core/emitter.js +38 -0
- package/vendor/map-engine/core/equal.d.ts +2 -0
- package/vendor/map-engine/core/equal.js +28 -0
- package/vendor/map-engine/core/errors.d.ts +20 -0
- package/vendor/map-engine/core/errors.js +34 -0
- package/vendor/map-engine/core/geometry-family.d.ts +3 -0
- package/vendor/map-engine/core/geometry-family.js +13 -0
- package/vendor/map-engine/core/index.d.ts +4 -0
- package/vendor/map-engine/core/index.js +3 -0
- package/vendor/map-engine/core/types.d.ts +709 -0
- package/vendor/map-engine/core/types.js +7 -0
- package/vendor/map-engine/data/annotations.d.ts +3 -0
- package/vendor/map-engine/data/annotations.js +63 -0
- package/vendor/map-engine/data/contracts.d.ts +172 -0
- package/vendor/map-engine/data/contracts.js +12 -0
- package/vendor/map-engine/data/index.d.ts +4 -0
- package/vendor/map-engine/data/index.js +3 -0
- package/vendor/map-engine/data/schema.d.ts +7 -0
- package/vendor/map-engine/data/schema.js +40 -0
- package/vendor/map-engine/geofence/evaluator.d.ts +35 -0
- package/vendor/map-engine/geofence/evaluator.js +172 -0
- package/vendor/map-engine/geofence/history.d.ts +9 -0
- package/vendor/map-engine/geofence/history.js +19 -0
- package/vendor/map-engine/geofence/index.d.ts +2 -0
- package/vendor/map-engine/geofence/index.js +2 -0
- package/vendor/map-engine/index.d.ts +27 -0
- package/vendor/map-engine/index.js +14 -0
- package/vendor/map-engine/layers/index.d.ts +1 -0
- package/vendor/map-engine/layers/index.js +1 -0
- package/vendor/map-engine/layers/layers.d.ts +49 -0
- package/vendor/map-engine/layers/layers.js +316 -0
- package/vendor/map-engine/maplibre/deck-host.d.ts +105 -0
- package/vendor/map-engine/maplibre/deck-host.js +401 -0
- package/vendor/map-engine/maplibre/icons.d.ts +17 -0
- package/vendor/map-engine/maplibre/icons.js +65 -0
- package/vendor/map-engine/maplibre/index.d.ts +3 -0
- package/vendor/map-engine/maplibre/index.js +2 -0
- package/vendor/map-engine/maplibre/map-like.d.ts +56 -0
- package/vendor/map-engine/maplibre/map-like.js +1 -0
- package/vendor/map-engine/maplibre/renderer.d.ts +173 -0
- package/vendor/map-engine/maplibre/renderer.js +889 -0
- package/vendor/map-engine/maplibre/style.d.ts +84 -0
- package/vendor/map-engine/maplibre/style.js +493 -0
- package/vendor/map-engine/present/decorations.d.ts +25 -0
- package/vendor/map-engine/present/decorations.js +115 -0
- package/vendor/map-engine/present/index.d.ts +2 -0
- package/vendor/map-engine/present/index.js +2 -0
- package/vendor/map-engine/present/present.d.ts +47 -0
- package/vendor/map-engine/present/present.js +149 -0
- package/vendor/map-engine/query/index.d.ts +1 -0
- package/vendor/map-engine/query/index.js +1 -0
- package/vendor/map-engine/query/planner.d.ts +26 -0
- package/vendor/map-engine/query/planner.js +47 -0
- package/vendor/map-engine/react/MapView.d.ts +87 -0
- package/vendor/map-engine/react/MapView.js +270 -0
- package/vendor/map-engine/react/context.d.ts +39 -0
- package/vendor/map-engine/react/context.js +94 -0
- package/vendor/map-engine/react/index.d.ts +2 -0
- package/vendor/map-engine/react/index.js +2 -0
- package/vendor/map-engine/react/store.d.ts +19 -0
- package/vendor/map-engine/react/store.js +18 -0
- package/vendor/map-engine/realtime/apply.d.ts +74 -0
- package/vendor/map-engine/realtime/apply.js +155 -0
- package/vendor/map-engine/realtime/index.d.ts +1 -0
- package/vendor/map-engine/realtime/index.js +1 -0
- package/vendor/map-engine/render/index.d.ts +1 -0
- package/vendor/map-engine/render/index.js +1 -0
- package/vendor/map-engine/render/offline.d.ts +8 -0
- package/vendor/map-engine/render/offline.js +47 -0
- package/vendor/map-engine/render/renderer.d.ts +74 -0
- package/vendor/map-engine/render/renderer.js +1 -0
- package/vendor/map-engine/render/terrarium.d.ts +48 -0
- package/vendor/map-engine/render/terrarium.js +110 -0
- package/vendor/map-engine/runtime/drawing.d.ts +28 -0
- package/vendor/map-engine/runtime/drawing.js +58 -0
- package/vendor/map-engine/runtime/index.d.ts +5 -0
- package/vendor/map-engine/runtime/index.js +2 -0
- package/vendor/map-engine/runtime/offline.d.ts +24 -0
- package/vendor/map-engine/runtime/offline.js +37 -0
- package/vendor/map-engine/runtime/overlays.d.ts +25 -0
- package/vendor/map-engine/runtime/overlays.js +65 -0
- package/vendor/map-engine/runtime/runtime.d.ts +4 -0
- package/vendor/map-engine/runtime/runtime.js +2105 -0
- package/vendor/map-engine/runtime/types.d.ts +407 -0
- package/vendor/map-engine/runtime/types.js +1 -0
- package/vendor/map-engine/scene/index.d.ts +1 -0
- package/vendor/map-engine/scene/index.js +1 -0
- package/vendor/map-engine/scene/scene.d.ts +31 -0
- package/vendor/map-engine/scene/scene.js +216 -0
- package/vendor/map-engine/selection/index.d.ts +1 -0
- package/vendor/map-engine/selection/index.js +1 -0
- package/vendor/map-engine/selection/selection.d.ts +12 -0
- package/vendor/map-engine/selection/selection.js +28 -0
- package/vendor/map-engine/spatial/geojson.d.ts +15 -0
- package/vendor/map-engine/spatial/geojson.js +83 -0
- package/vendor/map-engine/spatial/geometry.d.ts +13 -0
- package/vendor/map-engine/spatial/geometry.js +206 -0
- package/vendor/map-engine/spatial/import.d.ts +27 -0
- package/vendor/map-engine/spatial/import.js +96 -0
- package/vendor/map-engine/spatial/index.d.ts +38 -0
- package/vendor/map-engine/spatial/index.js +37 -0
- package/vendor/map-engine/spatial/line-of-sight.d.ts +35 -0
- package/vendor/map-engine/spatial/line-of-sight.js +43 -0
- package/vendor/map-engine/spatial/measure.d.ts +28 -0
- package/vendor/map-engine/spatial/measure.js +90 -0
- package/vendor/map-engine/spatial/operations.d.ts +21 -0
- package/vendor/map-engine/spatial/operations.js +171 -0
- package/vendor/map-engine/spatial/query.d.ts +17 -0
- package/vendor/map-engine/spatial/query.js +88 -0
- package/vendor/map-engine/spatial/spatial-index.d.ts +24 -0
- package/vendor/map-engine/spatial/spatial-index.js +36 -0
- package/vendor/map-engine/spatial/volume-mesh.d.ts +19 -0
- package/vendor/map-engine/spatial/volume-mesh.js +56 -0
- package/vendor/map-engine/temporal/index.d.ts +3 -0
- package/vendor/map-engine/temporal/index.js +3 -0
- package/vendor/map-engine/temporal/journal.d.ts +20 -0
- package/vendor/map-engine/temporal/journal.js +34 -0
- package/vendor/map-engine/temporal/playback.d.ts +41 -0
- package/vendor/map-engine/temporal/playback.js +80 -0
- package/vendor/map-engine/temporal/tracks.d.ts +33 -0
- package/vendor/map-engine/temporal/tracks.js +119 -0
- package/vendor/map-engine/testing/annotation-store.d.ts +24 -0
- package/vendor/map-engine/testing/annotation-store.js +43 -0
- package/vendor/map-engine/testing/contracts.d.ts +41 -0
- package/vendor/map-engine/testing/contracts.js +328 -0
- package/vendor/map-engine/testing/fixtures-monitoring.d.ts +22 -0
- package/vendor/map-engine/testing/fixtures-monitoring.js +103 -0
- package/vendor/map-engine/testing/fixtures.d.ts +18 -0
- package/vendor/map-engine/testing/fixtures.js +28 -0
- package/vendor/map-engine/testing/index.d.ts +7 -0
- package/vendor/map-engine/testing/index.js +7 -0
- package/vendor/map-engine/testing/mock-ontology.d.ts +13 -0
- package/vendor/map-engine/testing/mock-ontology.js +24 -0
- package/vendor/map-engine/testing/mock-provider.d.ts +97 -0
- package/vendor/map-engine/testing/mock-provider.js +369 -0
- package/vendor/map-engine/testing/test-renderer.d.ts +72 -0
- package/vendor/map-engine/testing/test-renderer.js +153 -0
- package/vendor/map-engine/viewport/index.d.ts +1 -0
- package/vendor/map-engine/viewport/index.js +1 -0
- package/vendor/map-engine/viewport/viewport.d.ts +19 -0
- package/vendor/map-engine/viewport/viewport.js +102 -0
- package/vendor/map-provider-uns/client.d.ts +75 -0
- package/vendor/map-provider-uns/client.js +111 -0
- package/vendor/map-provider-uns/index.d.ts +2 -0
- package/vendor/map-provider-uns/index.js +2 -0
- package/vendor/map-provider-uns/provider.d.ts +131 -0
- package/vendor/map-provider-uns/provider.js +561 -0
package/README.md
CHANGED
|
@@ -51,4 +51,37 @@ const { data, loading, error } = useRequest(url, { auth: 'iosense' });
|
|
|
51
51
|
|
|
52
52
|
`auth: 'iosense'` adds the viewer's token and is refused for any host that is not IOSense's.
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
## Maps (`@faclon-labs/app-sdk/map`)
|
|
55
|
+
|
|
56
|
+
The IO Studio Map Engine on UNS data: a declarative `MapConfig`, the React `MapView`, the MapLibre renderer, the
|
|
57
|
+
UNS provider, and the agent commands. Install MapLibre next to the SDK:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install @faclon-labs/app-sdk maplibre-gl
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
65
|
+
import { MapView, MapLibreRenderer, useUnsMapSource, type MapConfig } from '@faclon-labs/app-sdk/map';
|
|
66
|
+
// Vite: without this line the map stays empty (the engine warns after 8 s).
|
|
67
|
+
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
|
|
68
|
+
|
|
69
|
+
function PlantMap({ config }: { config: MapConfig }) {
|
|
70
|
+
const source = useUnsMapSource({ workspace: 'ws_…' }); // the viewer's session; the UNS decides what they see
|
|
71
|
+
return <MapView style={{ height: '100vh' }} config={config} {...source.props} createRenderer={() => new MapLibreRenderer({ workerUrl })} />;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- `source.uns.listDatasets()` lists every spatial class in the workspace with its properties.
|
|
76
|
+
- On sample data (`auth="optional"`, nobody signed in) the map shows `sample` records you pass to
|
|
77
|
+
`useUnsMapSource`. `@faclon-labs/app-sdk/map/testing` has fixtures and an in-memory provider.
|
|
78
|
+
- The UNS host is `configure({ unsBaseUrl })`, else worked out from `apiBaseUrl`
|
|
79
|
+
(`appserver.X` → `uns-backend-server.X`). **The UNS backend answers only IOSense's own origins (CORS)**: an app
|
|
80
|
+
served from elsewhere needs a pass-through that allows it, set as `unsBaseUrl`.
|
|
81
|
+
- 3D globe: `npm install cesium`, then `import { CesiumRenderer } from '@faclon-labs/app-sdk/map/globe'` and
|
|
82
|
+
`createRenderer={() => new CesiumRenderer()}`. A 2D app never downloads Cesium.
|
|
83
|
+
|
|
84
|
+
The engine comes from the MapEngine repo: `npm run build` copies it into `vendor/` (set `MAP_ENGINE_DIR` if the
|
|
85
|
+
checkout is not next to io-lens-mfe). `scripts/smoke-map.sh` installs the packed SDK into a fresh app and checks it.
|
|
86
|
+
|
|
87
|
+
Peer dependencies: React 18 or later; `maplibre-gl` (v5+) for `./map`; `cesium` for `./map/globe`.
|
package/dist/SignIn.js
CHANGED
|
@@ -40,7 +40,7 @@ export function SignIn({ appName, apiBaseUrl, onSignedIn }) {
|
|
|
40
40
|
}
|
|
41
41
|
catch (err) {
|
|
42
42
|
// The server's own words ("Invalid or expired token.") say what to do: mint a new one.
|
|
43
|
-
setError(`${err instanceof Error ? err.message : 'IOSense did not accept this token.'} An SSO token works once
|
|
43
|
+
setError(`${err instanceof Error ? err.message : 'IOSense did not accept this token.'} An SSO token works once. Copy a fresh one.`);
|
|
44
44
|
}
|
|
45
45
|
finally {
|
|
46
46
|
setBusy(false);
|
|
@@ -68,5 +68,5 @@ export function SignIn({ appName, apiBaseUrl, onSignedIn }) {
|
|
|
68
68
|
onSignedIn(value);
|
|
69
69
|
}
|
|
70
70
|
const canSubmit = !busy && token.trim().length > 0;
|
|
71
|
-
return (_jsx("div", { "data-iosense-signin": true, style: { minHeight: '100vh', display: 'grid', placeItems: 'center', padding: 24, background: 'var(--background, #f7f7f4)', color: 'var(--foreground, #161616)', fontFamily: 'inherit' }, children: _jsxs("form", { onSubmit: submit, style: { width: 'min(380px, 100%)', display: 'flex', flexDirection: 'column', gap: 12, padding: 24, borderRadius: 12, background: 'var(--card, #fff)', border: '1px solid var(--border, #e2e0da)' }, children: [_jsxs("div", { children: [_jsxs("h1", { style: { margin: 0, fontSize: 18, fontWeight: 600 }, children: ["Sign in to ", appName] }), _jsx("p", { style: { margin: '4px 0 0', fontSize: 13, color: 'var(--muted-foreground, #5c5c5c)' }, children: "This app reads your plant through IOSense. Paste an SSO token from your IOSense session." })] }), _jsxs("label", { style: { display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, fontWeight: 500 }, children: ["SSO token", _jsx("input", { name: "token", autoComplete: "off", autoFocus: true, spellCheck: false, placeholder: "Paste an SSO token from IOSense", value: token, onChange: (e) => setToken(e.target.value), disabled: busy, style: { width: '100%', boxSizing: 'border-box', height: 40, padding: '0 12px', border: '1px solid var(--border, #d4d4d8)', borderRadius: 8, background: 'var(--background, #fff)', color: 'inherit', font: 'inherit' } })] }), error && (_jsx("p", { role: "alert", style: { margin: 0, fontSize: 13, color: 'var(--destructive, #b4302c)' }, children: error })), _jsx("button", { type: "submit", disabled: !canSubmit, style: { height: 40, border: 0, borderRadius: 999, background: 'var(--primary, #1364f1)', color: 'var(--primary-foreground, #fff)', font: 'inherit', fontWeight: 500, cursor: busy ? 'progress' : 'pointer', opacity: canSubmit ? 1 : 0.6 }, children: busy ? 'Checking…' : 'Continue' }), _jsx("p", { style: { margin: 0, fontSize: 12, color: 'var(--muted-foreground, #5c5c5c)' }, children: "Opened from the IOSense launchpad, this app signs you in on its own
|
|
71
|
+
return (_jsx("div", { "data-iosense-signin": true, style: { minHeight: '100vh', display: 'grid', placeItems: 'center', padding: 24, background: 'var(--background, #f7f7f4)', color: 'var(--foreground, #161616)', fontFamily: 'inherit' }, children: _jsxs("form", { onSubmit: submit, style: { width: 'min(380px, 100%)', display: 'flex', flexDirection: 'column', gap: 12, padding: 24, borderRadius: 12, background: 'var(--card, #fff)', border: '1px solid var(--border, #e2e0da)' }, children: [_jsxs("div", { children: [_jsxs("h1", { style: { margin: 0, fontSize: 18, fontWeight: 600 }, children: ["Sign in to ", appName] }), _jsx("p", { style: { margin: '4px 0 0', fontSize: 13, color: 'var(--muted-foreground, #5c5c5c)' }, children: "This app reads your plant through IOSense. Paste an SSO token from your IOSense session." })] }), _jsxs("label", { style: { display: 'flex', flexDirection: 'column', gap: 4, fontSize: 13, fontWeight: 500 }, children: ["SSO token", _jsx("input", { name: "token", autoComplete: "off", autoFocus: true, spellCheck: false, placeholder: "Paste an SSO token from IOSense", value: token, onChange: (e) => setToken(e.target.value), disabled: busy, style: { width: '100%', boxSizing: 'border-box', height: 40, padding: '0 12px', border: '1px solid var(--border, #d4d4d8)', borderRadius: 8, background: 'var(--background, #fff)', color: 'inherit', font: 'inherit' } })] }), error && (_jsx("p", { role: "alert", style: { margin: 0, fontSize: 13, color: 'var(--destructive, #b4302c)' }, children: error })), _jsx("button", { type: "submit", disabled: !canSubmit, style: { height: 40, border: 0, borderRadius: 999, background: 'var(--primary, #1364f1)', color: 'var(--primary-foreground, #fff)', font: 'inherit', fontWeight: 500, cursor: busy ? 'progress' : 'pointer', opacity: canSubmit ? 1 : 0.6 }, children: busy ? 'Checking…' : 'Continue' }), _jsx("p", { style: { margin: 0, fontSize: 12, color: 'var(--muted-foreground, #5c5c5c)' }, children: "Opened from the IOSense launchpad, this app signs you in on its own. This screen is for opening it by its own address." })] }) }));
|
|
72
72
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -12,6 +12,11 @@ export interface IOSenseConfig {
|
|
|
12
12
|
tokenCookie: string;
|
|
13
13
|
/** Where the session is kept in this browser. */
|
|
14
14
|
storageKey: string;
|
|
15
|
+
/**
|
|
16
|
+
* The UNS backend the map reads (`@faclon-labs/app-sdk/map`). Empty: worked out from `apiBaseUrl`
|
|
17
|
+
* (`appserver.X` → `uns-backend-server.X`).
|
|
18
|
+
*/
|
|
19
|
+
unsBaseUrl: string;
|
|
15
20
|
}
|
|
16
21
|
export declare function configure(next: Partial<IOSenseConfig>): void;
|
|
17
22
|
export declare const getConfig: () => Readonly<IOSenseConfig>;
|
package/dist/config.js
CHANGED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @faclon-labs/app-sdk/map/globe — the 3D globe renderer (Cesium). Install `cesium` next to the SDK; pass
|
|
3
|
+
* `createRenderer={() => new CesiumRenderer()}` to `MapView`. Everything else comes from `@faclon-labs/app-sdk/map`.
|
|
4
|
+
*/
|
|
5
|
+
export * from '../../vendor/map-engine/cesium/index.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @faclon-labs/app-sdk/map/globe — the 3D globe renderer (Cesium). Install `cesium` next to the SDK; pass
|
|
3
|
+
* `createRenderer={() => new CesiumRenderer()}` to `MapView`. Everything else comes from `@faclon-labs/app-sdk/map`.
|
|
4
|
+
*/
|
|
5
|
+
export * from '../../vendor/map-engine/cesium/index.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @faclon-labs/app-sdk/map — maps on UNS data.
|
|
3
|
+
*
|
|
4
|
+
* The IO Studio Map Engine (runtime, contracts, spatial API, commands, agent transports), its React view and
|
|
5
|
+
* MapLibre renderer, and the UNS provider — plus `useUnsMapSource`, which connects the provider to the viewer's
|
|
6
|
+
* session. The 3D globe (Cesium) is a separate entry, `@faclon-labs/app-sdk/map/globe`, so a 2D app never
|
|
7
|
+
* downloads it.
|
|
8
|
+
*
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { MapView, MapLibreRenderer, useUnsMapSource } from '@faclon-labs/app-sdk/map';
|
|
11
|
+
* import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
|
|
12
|
+
*
|
|
13
|
+
* const source = useUnsMapSource({ workspace: 'ws_…' });
|
|
14
|
+
* <MapView {...source.props} config={config} createRenderer={() => new MapLibreRenderer({ workerUrl })} />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export * from '../../vendor/map-engine/index.js';
|
|
18
|
+
export * from '../../vendor/map-engine/react/index.js';
|
|
19
|
+
export * from '../../vendor/map-engine/maplibre/index.js';
|
|
20
|
+
export * from '../../vendor/map-provider-uns/index.js';
|
|
21
|
+
export { useUnsMapSource, unsBaseUrlFor, type UnsMapSource, type UnsMapSourceOptions, type UnsMapSourceProps } from './source.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @faclon-labs/app-sdk/map — maps on UNS data.
|
|
3
|
+
*
|
|
4
|
+
* The IO Studio Map Engine (runtime, contracts, spatial API, commands, agent transports), its React view and
|
|
5
|
+
* MapLibre renderer, and the UNS provider — plus `useUnsMapSource`, which connects the provider to the viewer's
|
|
6
|
+
* session. The 3D globe (Cesium) is a separate entry, `@faclon-labs/app-sdk/map/globe`, so a 2D app never
|
|
7
|
+
* downloads it.
|
|
8
|
+
*
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { MapView, MapLibreRenderer, useUnsMapSource } from '@faclon-labs/app-sdk/map';
|
|
11
|
+
* import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
|
|
12
|
+
*
|
|
13
|
+
* const source = useUnsMapSource({ workspace: 'ws_…' });
|
|
14
|
+
* <MapView {...source.props} config={config} createRenderer={() => new MapLibreRenderer({ workerUrl })} />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export * from '../../vendor/map-engine/index.js';
|
|
18
|
+
export * from '../../vendor/map-engine/react/index.js';
|
|
19
|
+
export * from '../../vendor/map-engine/maplibre/index.js';
|
|
20
|
+
export * from '../../vendor/map-provider-uns/index.js';
|
|
21
|
+
export { useUnsMapSource, unsBaseUrlFor } from './source.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AuthContext, JournalProvider, LinkProvider, OntologySpatialResolver, RealtimeProvider, SpatialDataProvider, SpatialObject, TrackProvider } from '../../vendor/map-engine/index.js';
|
|
2
|
+
import { UnsSpatialProvider } from '../../vendor/map-provider-uns/index.js';
|
|
3
|
+
import { type MockRecord } from '../../vendor/map-engine/testing/index.js';
|
|
4
|
+
export interface UnsMapSourceOptions {
|
|
5
|
+
/** The UNS workspace id (`ws_…`) whose spatial nodes the map shows. */
|
|
6
|
+
workspace: string;
|
|
7
|
+
/** Shown as the datasets' source. */
|
|
8
|
+
workspaceName?: string;
|
|
9
|
+
/** The UNS backend. Default: `configure({ unsBaseUrl })`, else worked out from the session's `apiBaseUrl`. */
|
|
10
|
+
unsBaseUrl?: string;
|
|
11
|
+
/** How often live values are read. Default 3000 ms. */
|
|
12
|
+
pollMs?: number;
|
|
13
|
+
/**
|
|
14
|
+
* What the map shows while the app is on sample data (nobody signed in with `auth="optional"`). Give each record
|
|
15
|
+
* the `ontologyType` your layers ask for. Default: nothing — the layers stay empty.
|
|
16
|
+
*/
|
|
17
|
+
sample?: Array<MockRecord | SpatialObject>;
|
|
18
|
+
}
|
|
19
|
+
/** Spread into `<MapView>`: the data side of a map. */
|
|
20
|
+
export interface UnsMapSourceProps {
|
|
21
|
+
provider: SpatialDataProvider;
|
|
22
|
+
realtime: RealtimeProvider;
|
|
23
|
+
history: TrackProvider;
|
|
24
|
+
ontology: OntologySpatialResolver;
|
|
25
|
+
journal: JournalProvider;
|
|
26
|
+
links: LinkProvider;
|
|
27
|
+
auth: AuthContext | null;
|
|
28
|
+
}
|
|
29
|
+
export interface UnsMapSource {
|
|
30
|
+
props: UnsMapSourceProps;
|
|
31
|
+
/** The UNS provider (null on sample data): `listDatasets()` gives every spatial class with its properties. */
|
|
32
|
+
uns: UnsSpatialProvider | null;
|
|
33
|
+
/** True while the map shows the app's sample records rather than the plant's. */
|
|
34
|
+
sample: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** `https://appserver.X` → `https://uns-backend-server.X`. Any other host: IOSense's production UNS. */
|
|
37
|
+
export declare function unsBaseUrlFor(apiBaseUrl: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* The UNS as a map data source, on the viewer's session: the token is read on every request, so a refreshed
|
|
40
|
+
* session is used at once, and handed to the engine as `auth` so the UNS decides what is visible. Inside
|
|
41
|
+
* `<IOSenseApp>` only.
|
|
42
|
+
*
|
|
43
|
+
* The UNS backend answers only IOSense's own origins (CORS). An app served from elsewhere sets `unsBaseUrl` to a
|
|
44
|
+
* pass-through that allows it.
|
|
45
|
+
*/
|
|
46
|
+
export declare function useUnsMapSource(options: UnsMapSourceOptions): UnsMapSource;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useMemo, useRef } from 'react';
|
|
2
|
+
import { UnsClient, UnsSpatialProvider } from '../../vendor/map-provider-uns/index.js';
|
|
3
|
+
import { MockOntologyResolver, MockSpatialProvider } from '../../vendor/map-engine/testing/index.js';
|
|
4
|
+
import { getConfig } from '../config.js';
|
|
5
|
+
import { useIOSense } from '../session.js';
|
|
6
|
+
/** `https://appserver.X` → `https://uns-backend-server.X`. Any other host: IOSense's production UNS. */
|
|
7
|
+
export function unsBaseUrlFor(apiBaseUrl) {
|
|
8
|
+
const m = /^(https?:\/\/)appserver\.(.+?)\/?$/.exec(apiBaseUrl);
|
|
9
|
+
return m ? `${m[1]}uns-backend-server.${m[2]}` : 'https://uns-backend-server.iosense.io';
|
|
10
|
+
}
|
|
11
|
+
function sampleOntology(records) {
|
|
12
|
+
const out = {};
|
|
13
|
+
for (const r of records)
|
|
14
|
+
if ('object' in r && r.ontologyType)
|
|
15
|
+
out[r.ontologyType] = r.object.geometry.type;
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The UNS as a map data source, on the viewer's session: the token is read on every request, so a refreshed
|
|
20
|
+
* session is used at once, and handed to the engine as `auth` so the UNS decides what is visible. Inside
|
|
21
|
+
* `<IOSenseApp>` only.
|
|
22
|
+
*
|
|
23
|
+
* The UNS backend answers only IOSense's own origins (CORS). An app served from elsewhere sets `unsBaseUrl` to a
|
|
24
|
+
* pass-through that allows it.
|
|
25
|
+
*/
|
|
26
|
+
export function useUnsMapSource(options) {
|
|
27
|
+
const { token, apiBaseUrl, sample } = useIOSense();
|
|
28
|
+
const tokenRef = useRef(token);
|
|
29
|
+
tokenRef.current = token;
|
|
30
|
+
const base = (options.unsBaseUrl || getConfig().unsBaseUrl || unsBaseUrlFor(apiBaseUrl)).replace(/\/$/, '');
|
|
31
|
+
// Sample records are read once per switch into sample mode; a new array each render does not rebuild the map.
|
|
32
|
+
const sampleRef = useRef(options.sample);
|
|
33
|
+
sampleRef.current = options.sample;
|
|
34
|
+
const built = useMemo(() => {
|
|
35
|
+
if (sample) {
|
|
36
|
+
const records = sampleRef.current ?? [];
|
|
37
|
+
const mock = new MockSpatialProvider(records, { latencyMs: 0 });
|
|
38
|
+
return { data: mock, ontology: new MockOntologyResolver(sampleOntology(records)), uns: null };
|
|
39
|
+
}
|
|
40
|
+
const client = new UnsClient({ baseUrl: base, token: () => tokenRef.current });
|
|
41
|
+
const uns = new UnsSpatialProvider({
|
|
42
|
+
client,
|
|
43
|
+
workspace: options.workspace,
|
|
44
|
+
...(options.workspaceName ? { workspaceName: options.workspaceName } : {}),
|
|
45
|
+
...(options.pollMs ? { pollMs: options.pollMs } : {}),
|
|
46
|
+
});
|
|
47
|
+
return { data: uns, ontology: uns.ontology, uns };
|
|
48
|
+
}, [sample, base, options.workspace, options.workspaceName, options.pollMs]);
|
|
49
|
+
// No dispose on unmount: polling stops by itself when the map's runtime unsubscribes, and React's dev double
|
|
50
|
+
// effects would otherwise cut a live map's subscription.
|
|
51
|
+
const auth = useMemo(() => (token && !sample ? { token } : null), [token, sample]);
|
|
52
|
+
const props = useMemo(() => ({ provider: built.data, realtime: built.data, history: built.data, ontology: built.ontology, journal: built.data, links: built.data, auth }), [built, auth]);
|
|
53
|
+
return { props, uns: built.uns, sample };
|
|
54
|
+
}
|
package/dist/session.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export interface IOSenseSession {
|
|
|
13
13
|
/** Forget the session in this browser and show the sign-in screen again. */
|
|
14
14
|
signOut: () => void;
|
|
15
15
|
}
|
|
16
|
-
export declare const SAMPLE_NOTICE = "Sample data
|
|
16
|
+
export declare const SAMPLE_NOTICE = "Sample data: not live plant readings";
|
|
17
17
|
export declare const SessionContext: import("react").Context<IOSenseSession | null>;
|
|
18
18
|
/** The session of the nearest `<IOSenseApp>`. Throws outside one. */
|
|
19
19
|
export declare function useIOSense(): IOSenseSession;
|
package/dist/session.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useContext } from 'react';
|
|
2
|
-
export const SAMPLE_NOTICE = 'Sample data
|
|
2
|
+
export const SAMPLE_NOTICE = 'Sample data: not live plant readings';
|
|
3
3
|
export const SessionContext = createContext(null);
|
|
4
4
|
/** The session of the nearest `<IOSenseApp>`. Throws outside one. */
|
|
5
5
|
export function useIOSense() {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faclon-labs/app-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "IOSense sign-in
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "IOSense sign-in, plant data and maps for React apps: the launchpad SSO session, UNS latest values and series, the signed-in user, requests to IOSense's APIs, and the Map Engine on UNS (./map).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -10,28 +10,78 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./map": {
|
|
15
|
+
"types": "./dist/map/index.d.ts",
|
|
16
|
+
"import": "./dist/map/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./map/globe": {
|
|
19
|
+
"types": "./dist/map/globe.d.ts",
|
|
20
|
+
"import": "./dist/map/globe.js"
|
|
21
|
+
},
|
|
22
|
+
"./map/testing": {
|
|
23
|
+
"types": "./dist/map/testing.d.ts",
|
|
24
|
+
"import": "./dist/map/testing.js"
|
|
13
25
|
}
|
|
14
26
|
},
|
|
15
27
|
"files": [
|
|
16
28
|
"dist",
|
|
29
|
+
"vendor",
|
|
17
30
|
"README.md"
|
|
18
31
|
],
|
|
19
32
|
"sideEffects": false,
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@deck.gl/core": "~9.4.0",
|
|
35
|
+
"@deck.gl/layers": "~9.4.0",
|
|
36
|
+
"@deck.gl/mapbox": "~9.4.0",
|
|
37
|
+
"@deck.gl/mesh-layers": "~9.4.0",
|
|
38
|
+
"@loaders.gl/core": "^4.5.2",
|
|
39
|
+
"@loaders.gl/gltf": "^4.5.2",
|
|
40
|
+
"@luma.gl/core": "~9.4.2",
|
|
41
|
+
"@turf/area": "^7.4.0",
|
|
42
|
+
"@turf/boolean-contains": "^7.4.0",
|
|
43
|
+
"@turf/boolean-intersects": "^7.4.0",
|
|
44
|
+
"@turf/boolean-within": "^7.4.0",
|
|
45
|
+
"@turf/circle": "^7.4.0",
|
|
46
|
+
"@turf/distance": "^7.4.0",
|
|
47
|
+
"@turf/kinks": "^7.4.0",
|
|
48
|
+
"@turf/line-intersect": "^7.4.0",
|
|
49
|
+
"@turf/point-on-feature": "^7.4.0",
|
|
50
|
+
"@turf/point-to-line-distance": "^7.4.0",
|
|
51
|
+
"@turf/point-to-polygon-distance": "^7.4.0",
|
|
52
|
+
"@types/geojson": "7946.0.16",
|
|
53
|
+
"maplibre-contour": "^0.1.1",
|
|
54
|
+
"pmtiles": "^4.5.0",
|
|
55
|
+
"rbush": "^4.0.1"
|
|
56
|
+
},
|
|
20
57
|
"peerDependencies": {
|
|
21
|
-
"react": ">=18"
|
|
58
|
+
"react": ">=18",
|
|
59
|
+
"maplibre-gl": ">=5.0.0",
|
|
60
|
+
"cesium": ">=1.120.0"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"maplibre-gl": {
|
|
64
|
+
"optional": true
|
|
65
|
+
},
|
|
66
|
+
"cesium": {
|
|
67
|
+
"optional": true
|
|
68
|
+
}
|
|
22
69
|
},
|
|
23
70
|
"keywords": [
|
|
24
71
|
"iosense",
|
|
25
72
|
"faclon",
|
|
26
73
|
"uns",
|
|
27
74
|
"react",
|
|
28
|
-
"sso"
|
|
75
|
+
"sso",
|
|
76
|
+
"map",
|
|
77
|
+
"maplibre"
|
|
29
78
|
],
|
|
30
79
|
"license": "UNLICENSED",
|
|
31
80
|
"publishConfig": {
|
|
32
81
|
"access": "public"
|
|
33
82
|
},
|
|
34
83
|
"scripts": {
|
|
35
|
-
"
|
|
84
|
+
"vendor": "node scripts/vendor-map-engine.mjs",
|
|
85
|
+
"build": "node scripts/vendor-map-engine.mjs && rm -rf dist && tsc -p tsconfig.json"
|
|
36
86
|
}
|
|
37
87
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Built from MapEngine bcf2a34 — do not edit; run npm run vendor.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Ground metres per screen pixel at a zoom and latitude (web-map convention). */
|
|
2
|
+
export declare function metresPerPixel(zoom: number, latitude: number): number;
|
|
3
|
+
/** Distance from the camera to the centre that shows `viewHeightPx` pixels of ground at `zoom` (vertical FOV in radians). */
|
|
4
|
+
export declare function rangeForZoom(zoom: number, latitude: number, viewHeightPx: number, fovY: number): number;
|
|
5
|
+
/** The inverse of rangeForZoom. */
|
|
6
|
+
export declare function zoomForRange(range: number, latitude: number, viewHeightPx: number, fovY: number): number;
|
|
7
|
+
/** Engine pitch (0 = looking straight down, up to 85) → camera pitch in degrees (−90 = straight down). */
|
|
8
|
+
export declare const cameraPitch: (pitch: number | undefined) => number;
|
|
9
|
+
/** Camera pitch in degrees → engine pitch. */
|
|
10
|
+
export declare const enginePitch: (cameraPitchDeg: number) => number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The engine's viewport (centre, zoom, bearing, pitch) ↔ a 3D camera (Cesium). Pure maths, testable without WebGL.
|
|
3
|
+
*
|
|
4
|
+
* Zoom keeps its web-map meaning: at zoom z the ground under the centre measures 2π·R·cos(lat) / (256·2^z) metres
|
|
5
|
+
* per pixel. A camera that frames the view height at that scale stands `range` metres from the centre.
|
|
6
|
+
*/
|
|
7
|
+
const EARTH_RADIUS = 6_378_137;
|
|
8
|
+
/** Ground metres per screen pixel at a zoom and latitude (web-map convention). */
|
|
9
|
+
export function metresPerPixel(zoom, latitude) {
|
|
10
|
+
return (2 * Math.PI * EARTH_RADIUS * Math.cos((latitude * Math.PI) / 180)) / (256 * 2 ** zoom);
|
|
11
|
+
}
|
|
12
|
+
/** Distance from the camera to the centre that shows `viewHeightPx` pixels of ground at `zoom` (vertical FOV in radians). */
|
|
13
|
+
export function rangeForZoom(zoom, latitude, viewHeightPx, fovY) {
|
|
14
|
+
return (metresPerPixel(zoom, latitude) * viewHeightPx) / 2 / Math.tan(fovY / 2);
|
|
15
|
+
}
|
|
16
|
+
/** The inverse of rangeForZoom. */
|
|
17
|
+
export function zoomForRange(range, latitude, viewHeightPx, fovY) {
|
|
18
|
+
const mpp = (2 * range * Math.tan(fovY / 2)) / Math.max(1, viewHeightPx);
|
|
19
|
+
const z = Math.log2((2 * Math.PI * EARTH_RADIUS * Math.cos((latitude * Math.PI) / 180)) / (256 * mpp));
|
|
20
|
+
return Math.max(0, Math.min(24, z));
|
|
21
|
+
}
|
|
22
|
+
/** Engine pitch (0 = looking straight down, up to 85) → camera pitch in degrees (−90 = straight down). */
|
|
23
|
+
export const cameraPitch = (pitch) => -90 + Math.max(0, Math.min(85, pitch ?? 0));
|
|
24
|
+
/** Camera pitch in degrees → engine pitch. */
|
|
25
|
+
export const enginePitch = (cameraPitchDeg) => Math.max(0, Math.min(85, 90 + cameraPitchDeg));
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CesiumRenderer — the full-3D renderer (ADR-027, phase 3D): a true globe with terrain, objects at their real height,
|
|
3
|
+
* models and extrusions, behind the same Renderer contract as MapLibre. The runtime can switch to it and back
|
|
4
|
+
* (setRenderer) keeping layers, camera, selection and time.
|
|
5
|
+
*
|
|
6
|
+
* - No Cesium Ion and no cloud service: imagery from the basemap's tile URL, terrain from the same DEM tiles MapLibre
|
|
7
|
+
* uses (terrarium.ts), static assets served from `baseUrl` (self-hostable).
|
|
8
|
+
* - One Cesium entity per scene object; markers stay visible over terrain; areas and lines drape on the ground.
|
|
9
|
+
* - Heights (ADR-028): msl as-is in the same frame as the (sea-level) terrain, agl relative to the ground,
|
|
10
|
+
* ellipsoid warned once (no geoid model). Scene vertical exaggeration applies to terrain and heights alike.
|
|
11
|
+
* No business logic, no data queries; picks report stable objectIds.
|
|
12
|
+
*/
|
|
13
|
+
import type * as CesiumNS from 'cesium';
|
|
14
|
+
import type { BasemapConfig, MapConfig, MapViewport, Position, RendererCapabilities, ScenePatch, SceneState, Size, TerrainConfig, TilesetConfig, Unsubscribe } from '../core/types.js';
|
|
15
|
+
import type { MapClickEvent, PickEvent, Renderer, RendererOptions } from '../render/renderer.js';
|
|
16
|
+
type C = typeof CesiumNS;
|
|
17
|
+
type Listener<T> = (value: T) => void;
|
|
18
|
+
export interface CesiumTheme {
|
|
19
|
+
markerColor: string;
|
|
20
|
+
lineColor: string;
|
|
21
|
+
fillColor: string;
|
|
22
|
+
trackColor: string;
|
|
23
|
+
selectionColor: string;
|
|
24
|
+
hoverColor: string;
|
|
25
|
+
labelColor: string;
|
|
26
|
+
labelHalo: string;
|
|
27
|
+
background: string;
|
|
28
|
+
}
|
|
29
|
+
export declare const DEFAULT_CESIUM_THEME: CesiumTheme;
|
|
30
|
+
export interface CesiumRendererOptions {
|
|
31
|
+
/** Inject the module (tests, or apps that loaded it). Default: lazy `import('cesium')`. */
|
|
32
|
+
cesium?: C;
|
|
33
|
+
/** Where Cesium's static assets (Workers, Assets, Widgets, ThirdParty) are served from. Required in the browser. */
|
|
34
|
+
baseUrl?: string;
|
|
35
|
+
theme?: Partial<CesiumTheme>;
|
|
36
|
+
/** Heightmap samples per terrain tile edge. Default 65. */
|
|
37
|
+
terrainSamples?: number;
|
|
38
|
+
}
|
|
39
|
+
export declare class CesiumRenderer implements Renderer {
|
|
40
|
+
private readonly options;
|
|
41
|
+
private lib;
|
|
42
|
+
private viewer;
|
|
43
|
+
private handler;
|
|
44
|
+
private readonly offs;
|
|
45
|
+
private gen;
|
|
46
|
+
private readonly theme;
|
|
47
|
+
private readonly layers;
|
|
48
|
+
private readonly objects;
|
|
49
|
+
/** Every entity id drawn for an object (shape, stem, outline, parts, label), so removal is complete. */
|
|
50
|
+
private readonly drawn;
|
|
51
|
+
/** How each point object was drawn, apart from where: when only its position changes it is moved, not rebuilt. */
|
|
52
|
+
private readonly looks;
|
|
53
|
+
private hoverKey;
|
|
54
|
+
private fontName;
|
|
55
|
+
private terrain;
|
|
56
|
+
/** Loaded 3D Tiles by id, with the config they were loaded from. */
|
|
57
|
+
private readonly tilesets;
|
|
58
|
+
private warnedEllipsoid;
|
|
59
|
+
private warnedStyleBasemap;
|
|
60
|
+
/** Longest side of each model file once measured (sizeMeters). */
|
|
61
|
+
private readonly extents;
|
|
62
|
+
private readonly measuring;
|
|
63
|
+
/** Ground under volume origins, as drawn (exaggerated metres), by position; filled by one batched terrain sample. */
|
|
64
|
+
private readonly grounds;
|
|
65
|
+
private readonly groundQueue;
|
|
66
|
+
private readonly listeners;
|
|
67
|
+
/** A true globe: heights, models, extrusions, sensor volumes and 3D Tiles. */
|
|
68
|
+
readonly capabilities: RendererCapabilities;
|
|
69
|
+
constructor(options?: CesiumRendererOptions);
|
|
70
|
+
initialize(container: HTMLElement, options: RendererOptions): Promise<void>;
|
|
71
|
+
setViewport(viewport: MapViewport, options?: {
|
|
72
|
+
animate?: boolean;
|
|
73
|
+
}): void;
|
|
74
|
+
render(scene: SceneState): void;
|
|
75
|
+
update(patch: ScenePatch): void;
|
|
76
|
+
/**
|
|
77
|
+
* Draws objects again, in batches. Cesium merges a removal and an add of the same entity id within one batch
|
|
78
|
+
* into "nothing changed", and its visualizers keep drawing the old entity — so all removals go in one batch,
|
|
79
|
+
* which is flushed before the adds.
|
|
80
|
+
*/
|
|
81
|
+
private redraw;
|
|
82
|
+
/** What a point object looks like apart from its position (layer, selection, properties). */
|
|
83
|
+
private lookOf;
|
|
84
|
+
/**
|
|
85
|
+
* Moves an already drawn point object when only its position changed (the common live update): the entity and
|
|
86
|
+
* its stem get the new position; nothing is rebuilt. False when it must be drawn again.
|
|
87
|
+
*/
|
|
88
|
+
private move;
|
|
89
|
+
resize(): void;
|
|
90
|
+
getSize(): Size;
|
|
91
|
+
project(position: Position): {
|
|
92
|
+
x: number;
|
|
93
|
+
y: number;
|
|
94
|
+
} | null;
|
|
95
|
+
onCameraMove(l: () => void): Unsubscribe;
|
|
96
|
+
setBasemap(basemap: BasemapConfig): Promise<void>;
|
|
97
|
+
/** Cesium always draws a globe; a flat (mercator) request keeps the globe, which reads the same up close. */
|
|
98
|
+
setProjection(_projection: NonNullable<MapConfig['projection']>): void;
|
|
99
|
+
setTerrain(terrain: TerrainConfig | null): void;
|
|
100
|
+
/** 3D Tiles scenery from URLs (no Cesium Ion): added, replaced, shown/hidden and removed by id. */
|
|
101
|
+
setTilesets(tilesets: TilesetConfig[]): void;
|
|
102
|
+
sampleElevation(positions: Position[]): Promise<Array<number | null>>;
|
|
103
|
+
destroy(): void;
|
|
104
|
+
onViewportChange(l: Listener<MapViewport>): Unsubscribe;
|
|
105
|
+
onPick(l: Listener<PickEvent>): Unsubscribe;
|
|
106
|
+
onMapClick(l: Listener<MapClickEvent>): Unsubscribe;
|
|
107
|
+
onHover(l: Listener<PickEvent | null>): Unsubscribe;
|
|
108
|
+
onError(l: Listener<Error>): Unsubscribe;
|
|
109
|
+
/** The basemap as Cesium imagery: a tile URL works as is; a vector style URL needs a raster fallback. */
|
|
110
|
+
private imageryLayer;
|
|
111
|
+
/** Terrain from the configured DEM tiles (same as MapLibre), or a smooth ellipsoid. */
|
|
112
|
+
private terrainProvider;
|
|
113
|
+
/** Takes the new layer list; returns the objects to draw again and the keys to drop (their layer went away). */
|
|
114
|
+
private applyLayers;
|
|
115
|
+
private drop;
|
|
116
|
+
/** Adds or replaces the entities of one scene object. */
|
|
117
|
+
private put;
|
|
118
|
+
/** Draws one scene object (nothing of it may be drawn yet). */
|
|
119
|
+
private draw;
|
|
120
|
+
/**
|
|
121
|
+
* A height as drawn (ADR-028): Cesium's vertical exaggeration scales the terrain but not absolute heights, so heights
|
|
122
|
+
* are scaled the same way to keep an aircraft's true relation to the (exaggerated) ground. `lift` multiplies the
|
|
123
|
+
* height above the ground; `relative` (agl) heights are measured from the ground Cesium places them on.
|
|
124
|
+
*/
|
|
125
|
+
/**
|
|
126
|
+
* How things on the ground are placed: clamped to the terrain when there is one; without terrain the ground is
|
|
127
|
+
* the ellipsoid, so height 0 directly — Cesium updates clamped billboards lazily, and a moving one lagged behind.
|
|
128
|
+
*/
|
|
129
|
+
private groundReference;
|
|
130
|
+
/**
|
|
131
|
+
* Contour lines (doc 28 G11) as Cesium's elevation-contour material on the globe. This renderer exaggerates the
|
|
132
|
+
* terrain itself, so the spacing is exaggerated the same way and the lines still sit on true heights.
|
|
133
|
+
*/
|
|
134
|
+
private applyContours;
|
|
135
|
+
/** The drawn ground height under a point: cached, else the loaded tiles' guess now and a precise sample soon. */
|
|
136
|
+
private groundHeight;
|
|
137
|
+
private sampleGrounds;
|
|
138
|
+
private drawnHeight;
|
|
139
|
+
/** Measures a model file once (its longest side), then redraws the objects that use it (sizeMeters). */
|
|
140
|
+
private measure;
|
|
141
|
+
private bindEvents;
|
|
142
|
+
private hitTest;
|
|
143
|
+
/** The ground (terrain, else ellipsoid) under a screen point. */
|
|
144
|
+
private groundAt;
|
|
145
|
+
private currentViewport;
|
|
146
|
+
private emitError;
|
|
147
|
+
private add;
|
|
148
|
+
}
|
|
149
|
+
export {};
|