diff --git a/public/config.schema.json b/public/config.schema.json index d092686..2a04556 100644 --- a/public/config.schema.json +++ b/public/config.schema.json @@ -36,6 +36,11 @@ "description": "Use latest data point in the last year, or the most recent data point within the last 15 seconds" } } + }, + "defaultVisibility": { + "type": "boolean", + "default": true, + "description": "Show this layer by default" } } } @@ -183,6 +188,11 @@ ] } } + }, + "defaultVisibility": { + "type": "boolean", + "default": true, + "description": "Show this layer by default" } } } @@ -305,6 +315,11 @@ ] } } + }, + "defaultVisibility": { + "type": "boolean", + "default": true, + "description": "Show this layer by default" } } } @@ -417,6 +432,11 @@ ] } } + }, + "defaultVisibility": { + "type": "boolean", + "default": true, + "description": "Show this layer by default" } } } @@ -500,6 +520,11 @@ ] } } + }, + "defaultVisibility": { + "type": "boolean", + "default": true, + "description": "Show this layer by default" } } } diff --git a/src/UIDataContext.tsx b/src/UIDataContext.tsx deleted file mode 100644 index 8421d73..0000000 --- a/src/UIDataContext.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from "react"; - -interface LayerData { - name: string; - id: string; - visible: boolean; - treePath?: number[]; -} - -interface UIContextData { - layers: LayerData[]; - register: (name: string, id: string, treePath?: number[]) => void; - toggleVisibility: (id: string) => void; - cameraTargetId: string; - setCameraTargetId: (id: string) => void; -} - - -export const UIDataContext = - React.createContext( - { - layers: [], - register: (name: string, id: string) => { }, - toggleVisibility: (id: string) => { }, - cameraTargetId: '', - setCameraTargetId: (id: string) => { } - } - ); - - -export function useUI(): UIContextData { - const [layers, setLayers] = React.useState([]); - const [cameraTargetId, setCameraTargetId] = React.useState(''); - - const register = (name: string, id: string, treePath?: number[]) => { - setLayers((prevState) => [...prevState, { name, id, visible: true, treePath }]); - } - - const toggleVisibility = (id: string) => { - setLayers(prevState => { - return prevState.map(c => { - if (c.id === id) { - const newVisibility = !c.visible; - if (c.treePath && c.treePath.length > 0) { - const children = prevState.filter(layer => layer.treePath && c.treePath && layer.treePath[0] === c.treePath[0] && layer.treePath.length > c.treePath.length); - if (!newVisibility) { - children.forEach(child => { - sessionStorage.setItem(`${child.id}-visible`, child.visible.toString()); - child.visible = false; - }); - } else { - children.forEach(child => { - child.visible = JSON.parse(sessionStorage.getItem(`${child.id}-visible`) || 'true'); - }); - } - } - return { ...c, visible: newVisibility }; - } - return c; - }); - }); - } - - return { layers, register, toggleVisibility, cameraTargetId, setCameraTargetId }; -} diff --git a/src/buildScene.tsx b/src/buildScene.tsx index 29add42..9c27f79 100644 --- a/src/buildScene.tsx +++ b/src/buildScene.tsx @@ -39,6 +39,7 @@ export function buildScene( positioning={positioning} treePath={getTreePath()} name={layer.mapName || "Ground Plane"} + visible={layer.defaultVisibility} /> ); } @@ -59,6 +60,7 @@ export function buildScene( dataSource={dataSource as UniverseTelemetrySource} name={layer.mapName || "Map"} treePath={getTreePath()} + visible={layer.defaultVisibility} /> ); }); @@ -74,6 +76,7 @@ export function buildScene( positioning={positioning} treePath={getTreePath()} name={layer.name || "Marker"} + visible={layer.defaultVisibility} /> ); } @@ -86,6 +89,7 @@ export function buildScene( dataSource={dataSource as UniverseTelemetrySource | undefined} treePath={getTreePath()} name={layer.name || "Point Cloud"} + visible={layer.defaultVisibility} /> ); }); @@ -102,6 +106,7 @@ export function buildScene( dataSource={dataSource as UniverseTelemetrySource} treePath={getTreePath()} name={layer.name || "Geometry"} + visible={layer.defaultVisibility} /> ); } @@ -117,6 +122,7 @@ export function buildScene( name={device.name} id={currentDeviceId || undefined} treePath={[devices.length]} + visible={device.defaultVisibility} > {mapLayers} {deviceLayers} diff --git a/src/config.ts b/src/config.ts index 8e25695..2a8285c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,16 +1,16 @@ -import { Authentication, App } from "@formant/data-sdk"; -import { TelemetryUniverseData } from "@formant/universe-connector"; -import { StreamType, UniverseDataSource } from "@formant/universe-core"; -import { DataSourceBuilder } from "./layers/utils/DataSourceBuilder"; -import { Positioning } from "./layers/common/Positioning"; -import { PositioningBuilder } from "./layers/utils/PositioningBuilder"; +import { Authentication, App } from '@formant/data-sdk'; +import { TelemetryUniverseData } from '@formant/universe-connector'; +import { StreamType, UniverseDataSource } from '@formant/universe-core'; +import { DataSourceBuilder } from './layers/utils/DataSourceBuilder'; +import { Positioning } from './layers/common/Positioning'; +import { PositioningBuilder } from './layers/utils/PositioningBuilder'; // get query strings const urlParams = new URLSearchParams(window.location.search); -const deviceId = urlParams.get("device") ?? undefined; +const deviceId = urlParams.get('device') ?? undefined; export type Viewer3DConfiguarationPositioning = { - positioningType?: "Fixed" | "Gps" | "Odometry" | "Transform Tree" | "Hud"; + positioningType?: 'Fixed' | 'Gps' | 'Odometry' | 'Transform Tree' | 'Hud'; x?: number; y?: number; z?: number; @@ -38,10 +38,11 @@ export type Viewer3DConfiguration = { pointCloudLayers?: { name?: string; dataSource?: Viewer3DConfigurationDataSource; + defaultVisibility?: boolean; }[]; mapLayers?: { - mapType?: "Ground Plane" | "World Map"; - worldMapType?: "Satellite" | "Street" | "Satellite Street"; + mapType?: 'Ground Plane' | 'World Map'; + worldMapType?: 'Satellite' | 'Street' | 'Satellite Street'; mapName?: string; mapSize?: string; longitude?: string; @@ -49,18 +50,22 @@ export type Viewer3DConfiguration = { mapboxKey?: string; dataSource?: Viewer3DConfigurationDataSource; positioning?: Viewer3DConfiguarationPositioning; + defaultVisibility?: boolean; }[]; deviceVisualLayers?: { name?: string; - visualType?: "Circle"; + visualType?: 'Circle'; dataSource?: Viewer3DConfigurationDataSource; positioning?: Viewer3DConfiguarationPositioning; + defaultVisibility?: boolean; }[]; geometryLayers?: { name?: string; dataSource?: Viewer3DConfigurationDataSource; positioning?: Viewer3DConfiguarationPositioning; + defaultVisibility?: boolean; }[]; + defaultVisibility?: boolean; }[]; }; @@ -70,7 +75,7 @@ export function parseDataSource( if (dataSource.telemetryStreamName) { return DataSourceBuilder.telemetry( dataSource.telemetryStreamName, - (dataSource.telemetryStreamType as StreamType) || "json", + (dataSource.telemetryStreamType as StreamType) || 'json', dataSource.latestDataPoint ); } @@ -81,25 +86,25 @@ export function parsePositioning( positioning: Viewer3DConfiguarationPositioning ): Positioning { switch (positioning.positioningType) { - case "Fixed": + case 'Fixed': return PositioningBuilder.fixed( positioning.x || 0, positioning.y || 0, positioning.z || 0 ); - case "Gps": - return PositioningBuilder.gps(positioning.gpsStream || "", { + case 'Gps': + return PositioningBuilder.gps(positioning.gpsStream || '', { long: positioning.relativeLongitude || 0, lat: positioning.relativeLatitude || 0, }); - case "Odometry": + case 'Odometry': return PositioningBuilder.localization( - positioning.localizationStream || "" + positioning.localizationStream || '' ); - case "Transform Tree": + case 'Transform Tree': return PositioningBuilder.tranformTree( - positioning.transformTreeStream || "", - positioning.transformTreeEndPoint || "" + positioning.transformTreeStream || '', + positioning.transformTreeEndPoint || '' ); default: return PositioningBuilder.fixed(0, 0, 0); diff --git a/src/layers/DataVisualizationLayer.tsx b/src/layers/DataVisualizationLayer.tsx index 50eacab..66b5b05 100644 --- a/src/layers/DataVisualizationLayer.tsx +++ b/src/layers/DataVisualizationLayer.tsx @@ -87,8 +87,8 @@ export function DataVisualizationLayer(props: IDataVisualizationLayerProps) { const { register, layers } = useContext(UIDataContext); useEffect(() => { - const autoId = id || getUuid(JSON.stringify({ name, type, treePath })); - const registeredLayer = register(name || "Layer", autoId, type || LayerType.UNDEFINED, treePath); + const autoId = id || getUuid(JSON.stringify({ name, type, treePath, deviceId })); + const registeredLayer = register(name || "Layer", autoId, type || LayerType.UNDEFINED, treePath, visible); setThisLayer(registeredLayer); }, []); diff --git a/src/layers/common/UIDataContext.tsx b/src/layers/common/UIDataContext.tsx index 7d2e0e5..671f07f 100644 --- a/src/layers/common/UIDataContext.tsx +++ b/src/layers/common/UIDataContext.tsx @@ -11,7 +11,7 @@ export interface LayerData { interface UIContextData { layers: LayerData[]; - register: (name: string, id: string, type: LayerType, treePath?: number[]) => LayerData; + register: (name: string, id: string, type: LayerType, treePath?: number[], defaultVisibility?: boolean) => LayerData; toggleVisibility: (id: string) => void; cameraTargetId: string; setCameraTargetId: (id: string) => void; @@ -22,7 +22,7 @@ export const UIDataContext = React.createContext( { layers: [], - register: (name: string, id: string, type: LayerType, treePath?: number[]) => { return { name, id, type, visible: true, treePath } }, + register: (name: string, id: string, type: LayerType, treePath?: number[], defaultVisibility?: boolean) => { return { name, id, type, visible: true, treePath } }, toggleVisibility: (id: string) => { }, cameraTargetId: '', setCameraTargetId: (id: string) => { } @@ -34,9 +34,11 @@ export function useUI(): UIContextData { const [layers, setLayers] = React.useState([]); const [cameraTargetId, setCameraTargetId] = React.useState(''); - const register = (name: string, id: string, type: LayerType, treePath?: number[]) => { - const visible = JSON.parse(sessionStorage.getItem(`${id}-visible`) || 'true'); - const layer = { name, id, visible, type, treePath }; + const register = (name: string, id: string, type: LayerType, treePath?: number[], defaultVisibility?: boolean) => { + const storedVisibility = JSON.parse(sessionStorage.getItem(`${id}-visible`) || 'null'); + const visible = storedVisibility === null ? defaultVisibility : storedVisibility; + const layer = { name, id, visible: visible === undefined ? true : visible, type, treePath }; + setLayers(prevState => [...prevState, layer]); return layer;