diff --git a/packages/landing/src/components/layer.switcher.dropdown.tsx b/packages/landing/src/components/layer.switcher.dropdown.tsx index 1f3308ec4..572ccfc94 100644 --- a/packages/landing/src/components/layer.switcher.dropdown.tsx +++ b/packages/landing/src/components/layer.switcher.dropdown.tsx @@ -46,23 +46,60 @@ export class LayerSwitcherDropdown extends Component this.setState({ layers })); + Config.map.layers.then((layers) => { + this.setState({ layers }); + // This needs to run on next tick or the sate will not have updated + setTimeout(() => this.ensurePipelineSet(), 10); + }); this._events.push( - Config.map.on('layer', () => this.setState({ currentLayer: Config.map.layerKey })), + Config.map.on('layer', () => { + this.setState({ currentLayer: Config.map.layerKey }); + // This needs to run on next tick or the sate will not have updated + setTimeout(() => this.ensurePipelineSet(), 10); + }), Config.map.on('tileMatrix', () => this.forceUpdate()), ); } + /** + * When the layers list load it contains more information like the default pipeline which is needed to create the tile XYZ url + * so if the pipeline exists and its not set to the currently selected one update it + */ + ensurePipelineSet(): void { + const currentLayer = this.state.currentLayer; + if (currentLayer == null) return; + + const layer = this.getLayer(currentLayer); + if (layer?.pipeline) { + const [layerId, style] = currentLayer.split('::'); + Config.map.setLayerId(layerId, style, layer.pipeline); + } + } + override componentWillUnmount(): void { for (const e of this._events) e(); this._events = []; } + /** + * lookup a layer from the liast of layers used to render the dropdown + * @param layerId + * @returns the layer or null if its not found + */ + getLayer(layerId: string): LayerInfo | null { + if (this.state.layers == null) return null; + for (const layer of this.state.layers.values()) { + if (layer.id === layerId) return layer; + } + return null; + } + onLayerChange = (opt: Option | null): void => { if (opt == null) return; + const layer = this.getLayer(opt.value); const [layerId, style] = opt.value.split('::'); - Config.map.setLayerId(layerId, style); + Config.map.setLayerId(layerId, style, layer?.pipeline); gaEvent(GaEvent.Ui, 'layer:' + opt.value); // Configure the bounds of the map to match the new layer diff --git a/packages/landing/src/config.map.ts b/packages/landing/src/config.map.ts index ec5739eeb..5bb37f676 100644 --- a/packages/landing/src/config.map.ts +++ b/packages/landing/src/config.map.ts @@ -34,7 +34,12 @@ export interface Filter { export interface MapConfigEvents { location: [MapLocation]; tileMatrix: [TileMatrixSet]; - layer: [string, string | null | undefined]; + + /** Layer information was changed + * + * [ LayerId, Style?, Pipeline? ] + */ + layer: [string, string | null | undefined, string | null | undefined]; bounds: [LngLatBoundsLike]; filter: [Filter]; change: []; @@ -147,7 +152,7 @@ export class MapConfig extends Emitter { if (this.layerId === 'topographic' && this.style == null) this.style = 'topographic'; this.emit('tileMatrix', this.tileMatrix); - this.emit('layer', this.layerId, this.style); + this.emit('layer', this.layerId, this.style, this.pipeline); if (previousUrl !== MapConfig.toUrl(this)) this.emit('change'); } @@ -223,11 +228,12 @@ export class MapConfig extends Emitter { this.emit('change'); } - setLayerId(layer: string, style?: string | null): void { - if (this.layerId === layer && this.style === style) return; + setLayerId(layer: string, style: string | null = null, pipeline: string | null = null): void { + if (this.layerId === layer && this.style === style && this.pipeline === pipeline) return; this.layerId = layer; - this.style = style ?? null; - this.emit('layer', this.layerId, this.style); + this.style = style; + this.pipeline = pipeline; + this.emit('layer', this.layerId, this.style, this.pipeline); this.emit('change'); } @@ -250,6 +256,8 @@ export interface LayerInfo { lowerRight?: [number, number]; /** What projections are enabled for this layer */ projections: Set; + /** Is a pipeline required for the layer */ + pipeline?: string; } async function loadAllLayers(): Promise> { @@ -327,6 +335,14 @@ function addDefaultLayers(output: Map): void { category: 'Basemaps', }, + { + id: 'elevation', + name: 'Elevation', + projections: new Set([EpsgCode.Google]), + category: 'Basemaps', + pipeline: 'terrain-rgb', + }, + { id: 'scanned-aerial-imagery-pre-1990-01-01', name: 'Scanned Aerial Imagery pre 1 January 1990',