@@ -89,6 +89,51 @@ export function colormapMarkersSubsample(
8989 return markers ;
9090}
9191
92+ // frame/band select which slice to read; they must be flat query params, not in style JSON
93+ const RASTER_SOURCE_FILTER_KEYS = new Set ( [ "frame" , "band" ] ) ;
94+
95+ // Ingest defaults missing source_filters to { band: 1 }; that is not a real band selection.
96+ function isDefaultBandSourceFilter (
97+ sourceFilters : Record < string , unknown > ,
98+ ) : boolean {
99+ const keys = Object . keys ( sourceFilters ) ;
100+ return (
101+ keys . length === 1 &&
102+ keys [ 0 ] === "band" &&
103+ ( sourceFilters . band === 1 || sourceFilters . band === "1" )
104+ ) ;
105+ }
106+
107+ function sourceFiltersToStyleFilters (
108+ sourceFilters : Record < string , unknown > | undefined ,
109+ ) : StyleFilter [ ] {
110+ if ( ! sourceFilters || ! Object . keys ( sourceFilters ) . length ) return [ ] ;
111+ if ( isDefaultBandSourceFilter ( sourceFilters ) ) return [ ] ;
112+ return Object . entries ( sourceFilters ) . map ( ( [ k , v ] ) => ( {
113+ filter_by : k ,
114+ list : [ v ] ,
115+ include : true ,
116+ transparency : true ,
117+ apply : true ,
118+ } ) ) ;
119+ }
120+
121+ function getRasterSourceFilterParams ( filters : StyleFilter [ ] ) {
122+ const params : Record < string , string | number > = { } ;
123+ filters . forEach ( ( f ) => {
124+ if (
125+ f . apply &&
126+ f . filter_by &&
127+ f . include &&
128+ f . list ?. length === 1 &&
129+ RASTER_SOURCE_FILTER_KEYS . has ( f . filter_by )
130+ ) {
131+ params [ f . filter_by ] = f . list [ 0 ] ;
132+ }
133+ } ) ;
134+ return params ;
135+ }
136+
92137function getRasterTilesQuery ( styleSpec : StyleSpec , colormaps : Colormap [ ] ) {
93138 let query : Record < string , any > = { } ;
94139 const colorSpecs = styleSpec . colors || [ ] ;
@@ -126,13 +171,35 @@ function getRasterTilesQuery(styleSpec: StyleSpec, colormaps: Colormap[]) {
126171 }
127172 } ) ;
128173 styleSpec . filters . forEach ( ( f ) => {
129- if ( f . apply && f . filter_by && f . include && f . list ?. length === 1 ) {
174+ if (
175+ f . apply &&
176+ f . filter_by &&
177+ f . include &&
178+ f . list ?. length === 1 &&
179+ ! RASTER_SOURCE_FILTER_KEYS . has ( f . filter_by )
180+ ) {
130181 query [ f . filter_by ] = f . list [ 0 ] ;
131182 }
132183 } ) ;
133184 return query ;
134185}
135186
187+ function buildRasterTileQueryParams (
188+ styleSpec : StyleSpec ,
189+ filters : StyleFilter [ ] ,
190+ colormaps : Colormap [ ] ,
191+ ) {
192+ const params : Record < string , string > = { projection : "epsg:3857" } ;
193+ Object . entries ( getRasterSourceFilterParams ( filters ) ) . forEach ( ( [ key , value ] ) => {
194+ params [ key ] = String ( value ) ;
195+ } ) ;
196+ const styleQuery = getRasterTilesQuery ( { ...styleSpec , filters } , colormaps ) ;
197+ if ( Object . keys ( styleQuery ) . length ) {
198+ params . style = JSON . stringify ( styleQuery ) ;
199+ }
200+ return params ;
201+ }
202+
136203function getVectorColorPaintProperty (
137204 styleSpec : StyleSpec ,
138205 groupName : string ,
@@ -439,16 +506,7 @@ export const useStyleStore = defineStore("style", () => {
439506 const map = mapStore . getMap ( ) ;
440507 let filters : StyleFilter [ ] = styleSpec . filters || [ ] ;
441508 if ( frame ?. source_filters ) {
442- filters = [
443- ...filters ,
444- ...Object . entries ( frame . source_filters ) . map ( ( [ k , v ] ) => ( {
445- filter_by : k ,
446- list : [ v ] ,
447- include : true ,
448- transparency : true ,
449- apply : true ,
450- } ) ) ,
451- ] ;
509+ filters = [ ...filters , ...sourceFiltersToStyleFilters ( frame . source_filters ) ] ;
452510 }
453511 const mapLayer = map . getLayer ( mapLayerId ) as
454512 | MapLibreLayerWithMetadata
@@ -550,11 +608,13 @@ export const useStyleStore = defineStore("style", () => {
550608 const source = map . getSource ( mapLayer . source ) as RasterTileSource ;
551609 const sourceURL = mapStore . rasterSourceTileURLs [ mapLayer . source ] ;
552610 if ( source && sourceURL ) {
553- const newQueryParams : { projection : string ; style ?: string } = {
554- projection : "epsg:3857" ,
555- } ;
556- newQueryParams . style = JSON . stringify ( rasterTilesQuery ) ;
557- const newQuery = new URLSearchParams ( newQueryParams ) ;
611+ const newQuery = new URLSearchParams (
612+ buildRasterTileQueryParams (
613+ { ...styleSpec , filters } ,
614+ filters ,
615+ colormaps . value ,
616+ ) ,
617+ ) ;
558618 tileURL = sourceURL . split ( "?" ) [ 0 ] + "?" + newQuery . toString ( ) ;
559619 return { paint, tileURL } ;
560620 }
@@ -605,6 +665,9 @@ export const useStyleStore = defineStore("style", () => {
605665 selectedLayerStyles,
606666 fetchColormaps,
607667 getRasterTilesQuery,
668+ getRasterSourceFilterParams,
669+ buildRasterTileQueryParams,
670+ sourceFiltersToStyleFilters,
608671 colormapMarkersSubsample,
609672 getDefaultColor,
610673 getDefaultStyleSpec,
0 commit comments