@@ -58,7 +58,9 @@ const SingleBandPseudoColor = ({
5858 const bandRowsRef = useRef < IBandRow [ ] > ( [ ] ) ;
5959 const selectedFunctionRef = useRef < InterpolationType > ( ) ;
6060 const colorRampOptionsRef = useRef < ReadonlyJSONObject | undefined > ( ) ;
61+ const layerStateRef = useRef < ReadonlyJSONObject | undefined > ( ) ;
6162
63+ const [ layerState , setLayerState ] = useState < ReadonlyJSONObject > ( ) ;
6264 const [ selectedBand , setSelectedBand ] = useState ( 1 ) ;
6365 const [ stopRows , setStopRows ] = useState < IStopRow [ ] > ( [ ] ) ;
6466 const [ bandRows , setBandRows ] = useState < IBandRow [ ] > ( [ ] ) ;
@@ -75,9 +77,9 @@ const SingleBandPseudoColor = ({
7577 if ( ! layer ) {
7678 return ;
7779 }
80+ const stateDb = GlobalStateDbManager . getInstance ( ) . getStateDb ( ) ;
7881
7982 useEffect ( ( ) => {
80- getBandInfo ( ) ;
8183 setInitialFunction ( ) ;
8284
8385 okSignalPromise . promise . then ( okSignal => {
@@ -96,13 +98,25 @@ const SingleBandPseudoColor = ({
9698 buildColorInfo ( ) ;
9799 } , [ bandRows ] ) ;
98100
101+ useEffect ( ( ) => {
102+ layerStateRef . current = layerState ;
103+ getBandInfo ( ) ;
104+ } , [ layerState ] ) ;
105+
99106 useEffect ( ( ) => {
100107 stopRowsRef . current = stopRows ;
101108 selectedFunctionRef . current = selectedFunction ;
102109 colorRampOptionsRef . current = colorRampOptions ;
103110 } , [ stopRows , selectedFunction , colorRampOptions ] ) ;
104111
105- const setInitialFunction = ( ) => {
112+ const setInitialFunction = async ( ) => {
113+ const layerState = ( await stateDb ?. fetch (
114+ `jupytergis:${ layerId } `
115+ ) ) as ReadonlyJSONObject ;
116+
117+ setLayerState ( layerState ) ;
118+
119+ // Set initial function
106120 if ( ! layer . parameters ?. color ) {
107121 setSelectedFunction ( 'linear' ) ;
108122 return ;
@@ -126,27 +140,14 @@ const SingleBandPseudoColor = ({
126140 const getBandInfo = async ( ) => {
127141 const bandsArr : IBandRow [ ] = [ ] ;
128142 const source = context . model . getSource ( layer ?. parameters ?. source ) ;
129- const sourceId = layer . parameters ?. source ;
130143 const sourceInfo = source ?. parameters ?. urls [ 0 ] ;
131144
132145 if ( ! sourceInfo . url ) {
133146 return ;
134147 }
135148
136- let tifData ;
137-
138- const stateDb = GlobalStateDbManager . getInstance ( ) . getStateDb ( ) ;
139-
140- if ( stateDb ) {
141- const layerState = ( await stateDb . fetch (
142- `jupytergis:${ sourceId } `
143- ) ) as ReadonlyJSONObject ;
144-
145- console . log ( 'layerState' , layerState ) ;
146- if ( layerState && layerState . tifData ) {
147- tifData = JSON . parse ( layerState . tifData as string ) ;
148- }
149- console . log ( 'tifData' , tifData ) ;
149+ if ( stateDb && layerState && layerState . tifData ) {
150+ const tifData = JSON . parse ( layerState . tifData as string ) ;
150151
151152 tifData [ 'bands' ] . forEach ( ( bandData : TifBandData ) => {
152153 bandsArr . push ( {
@@ -166,9 +167,9 @@ const SingleBandPseudoColor = ({
166167 }
167168 } ;
168169
169- const buildColorInfo = ( ) => {
170+ const buildColorInfo = async ( ) => {
170171 // This it to parse a color object on the layer
171- if ( ! layer . parameters ?. color ) {
172+ if ( ! layer . parameters ?. color || ! layerState ) {
172173 return ;
173174 }
174175
@@ -178,6 +179,11 @@ const SingleBandPseudoColor = ({
178179 if ( typeof color === 'string' ) {
179180 return ;
180181 }
182+
183+ const isQuantile =
184+ ( ( layerState as ReadonlyJSONObject ) . selectedMode as string ) ===
185+ 'quantile' ;
186+
181187 const valueColorPairs : IStopRow [ ] = [ ] ;
182188
183189 // So if it's not a string then it's an array and we parse
@@ -191,7 +197,7 @@ const SingleBandPseudoColor = ({
191197 // Sixth and on is value:color pairs
192198 for ( let i = 5 ; i < color . length ; i += 2 ) {
193199 const obj : IStopRow = {
194- stop : scaleValue ( color [ i ] ) ,
200+ stop : scaleValue ( color [ i ] , isQuantile ) ,
195201 output : color [ i + 1 ]
196202 } ;
197203 valueColorPairs . push ( obj ) ;
@@ -208,7 +214,7 @@ const SingleBandPseudoColor = ({
208214 // Last element is fallback value
209215 for ( let i = 3 ; i < color . length - 1 ; i += 2 ) {
210216 const obj : IStopRow = {
211- stop : scaleValue ( color [ i ] [ 2 ] ) ,
217+ stop : scaleValue ( color [ i ] [ 2 ] , isQuantile ) ,
212218 output : color [ i + 1 ]
213219 } ;
214220 valueColorPairs . push ( obj ) ;
@@ -233,13 +239,12 @@ const SingleBandPseudoColor = ({
233239 return ;
234240 }
235241
236- const stateDb = GlobalStateDbManager . getInstance ( ) . getStateDb ( ) ;
237- const layerState = ( await stateDb ?. fetch (
238- `jupytergis:${ layerId } `
239- ) ) as ReadonlyJSONObject ;
242+ const isQuantile = layerStateRef . current
243+ ? ( layerStateRef . current . selectedMode as string ) === 'quantile'
244+ : false ;
240245
241246 stateDb ?. save ( `jupytergis:${ layerId } ` , {
242- ...layerState ,
247+ ...layerStateRef . current ,
243248 ...colorRampOptionsRef . current
244249 } ) ;
245250
@@ -269,7 +274,7 @@ const SingleBandPseudoColor = ({
269274 colorExpr . push ( 0.0 , [ 0.0 , 0.0 , 0.0 , 0.0 ] ) ;
270275
271276 stopRowsRef . current ?. map ( stop => {
272- colorExpr . push ( unscaleValue ( stop . stop ) ) ;
277+ colorExpr . push ( unscaleValue ( stop . stop , isQuantile ) ) ;
273278 colorExpr . push ( stop . output ) ;
274279 } ) ;
275280
@@ -287,7 +292,7 @@ const SingleBandPseudoColor = ({
287292 colorExpr . push ( [
288293 '<=' ,
289294 [ 'band' , selectedBand ] ,
290- unscaleValue ( stop . stop )
295+ unscaleValue ( stop . stop , isQuantile )
291296 ] ) ;
292297 colorExpr . push ( stop . output ) ;
293298 } ) ;
@@ -307,7 +312,7 @@ const SingleBandPseudoColor = ({
307312 colorExpr . push ( [
308313 '==' ,
309314 [ 'band' , selectedBand ] ,
310- unscaleValue ( stop . stop )
315+ unscaleValue ( stop . stop , isQuantile )
311316 ] ) ;
312317 colorExpr . push ( stop . output ) ;
313318 } ) ;
@@ -411,27 +416,26 @@ const SingleBandPseudoColor = ({
411416 setStopRows ( valueColorPairs ) ;
412417 } ;
413418
414- const scaleValue = ( bandValue : number ) => {
419+ const scaleValue = ( bandValue : number , isQuantile : boolean ) => {
415420 const currentBand = bandRows [ selectedBand - 1 ] ;
416421
417422 if ( ! currentBand ) {
418423 return bandValue ;
419424 }
420425
421- return (
422- ( bandValue * ( currentBand . stats . maximum - currentBand . stats . minimum ) ) /
423- ( 1 - 0 ) +
424- currentBand . stats . minimum
425- ) ;
426+ const min = isQuantile ? 1 : currentBand . stats . minimum ;
427+ const max = isQuantile ? 65535 : currentBand . stats . maximum ;
428+
429+ return ( bandValue * ( max - min ) ) / ( 1 - 0 ) + min ;
426430 } ;
427431
428- const unscaleValue = ( value : number ) => {
432+ const unscaleValue = ( value : number , isQuantile : boolean ) => {
429433 const currentBand = bandRowsRef . current [ selectedBand - 1 ] ;
430434
431- return (
432- ( value * ( 1 - 0 ) - currentBand . stats . minimum * ( 1 - 0 ) ) /
433- ( currentBand . stats . maximum - currentBand . stats . minimum )
434- ) ;
435+ const min = isQuantile ? 1 : currentBand . stats . minimum ;
436+ const max = isQuantile ? 65535 : currentBand . stats . maximum ;
437+
438+ return ( value * ( 1 - 0 ) - min * ( 1 - 0 ) ) / ( max - min ) ;
435439 } ;
436440
437441 return (
0 commit comments