1+ # pylint: disable=too-many-lines
12import base64
23import io
34import json
2526 StatisticalSurfaceAddress ,
2627 SurfaceAddress ,
2728 SurfaceArrayServer ,
29+ SurfaceImageServer ,
2830)
2931
3032from ._layer_model import DeckGLMapLayersModel
3133from ._tmp_well_pick_provider import WellPickProvider
3234from ._types import LayerTypes , SurfaceMode
35+ from ._utils import round_to_significant
3336from .layout import (
3437 DefaultSettings ,
3538 LayoutElements ,
3639 LayoutLabels ,
40+ SideBySideColorSelectorFlex ,
3741 SideBySideSelectorFlex ,
3842 Tabs ,
3943 update_map_layers ,
4448def plugin_callbacks (
4549 get_uuid : Callable ,
4650 ensemble_surface_providers : Dict [str , EnsembleSurfaceProvider ],
47- surface_server : SurfaceArrayServer ,
51+ surface_server : Union [ SurfaceArrayServer , SurfaceImageServer ] ,
4852 ensemble_fault_polygons_providers : Dict [str , EnsembleFaultPolygonsProvider ],
4953 fault_polygons_server : FaultPolygonsServer ,
5054 map_surface_names_to_fault_polygons : Dict [str , str ],
@@ -169,6 +173,79 @@ def _update_components_and_selected_data(
169173 ],
170174 )
171175
176+ @callback (
177+ Output (
178+ {
179+ "view" : MATCH ,
180+ "id" : get_uuid ("color-input-min" ),
181+ "tab" : MATCH ,
182+ },
183+ "value" ,
184+ ),
185+ Output (
186+ {
187+ "view" : MATCH ,
188+ "id" : get_uuid ("color-input-max" ),
189+ "tab" : MATCH ,
190+ },
191+ "value" ,
192+ ),
193+ Output (
194+ {
195+ "view" : MATCH ,
196+ "id" : get_uuid (LayoutElements .COLORSELECTIONS ),
197+ "selector" : "color_range" ,
198+ "tab" : MATCH ,
199+ },
200+ "value" ,
201+ ),
202+ Input (
203+ {
204+ "view" : MATCH ,
205+ "id" : get_uuid ("color-input-min" ),
206+ "tab" : MATCH ,
207+ },
208+ "value" ,
209+ ),
210+ Input (
211+ {
212+ "view" : MATCH ,
213+ "id" : get_uuid ("color-input-max" ),
214+ "tab" : MATCH ,
215+ },
216+ "value" ,
217+ ),
218+ Input (
219+ {
220+ "view" : MATCH ,
221+ "id" : get_uuid (LayoutElements .COLORSELECTIONS ),
222+ "selector" : "color_range" ,
223+ "tab" : MATCH ,
224+ },
225+ "value" ,
226+ ),
227+ )
228+ def color_inputs_to_color_range (
229+ min_value : float , max_value : float , color_range : List [float ]
230+ ) -> Tuple [float , float , List [float ]]:
231+ """Updates color_range with the values from the color inputs"""
232+
233+ try :
234+ min_value = round_to_significant (float (min_value ))
235+ max_value = round_to_significant (float (max_value ))
236+ color_range = [round_to_significant (float (val )) for val in color_range ]
237+ except ValueError :
238+ return no_update , no_update , no_update
239+
240+ ctx = callback_context .triggered
241+ if "color-input-min" in ctx [0 ]["prop_id" ]:
242+ return no_update , no_update , [min_value , color_range [1 ]]
243+ if "color-input-max" in ctx [0 ]["prop_id" ]:
244+ return no_update , no_update , [color_range [0 ], max_value ]
245+ if "color_range" in ctx [0 ]["prop_id" ]:
246+ return color_range [0 ], color_range [1 ], color_range
247+ return no_update , no_update , no_update
248+
172249 # 3rd callback
173250 @callback (
174251 Output (
@@ -253,15 +330,15 @@ def _update_color_components_and_value(
253330 return (
254331 selector_values ,
255332 [
256- SideBySideSelectorFlex (
333+ SideBySideColorSelectorFlex (
257334 tab ,
258335 get_uuid ,
259336 selector = id_val ["selector" ],
260337 view_data = [
261338 data [id_val ["selector" ]] for data in color_component_properties
262339 ],
263340 link = id_val ["selector" ] in links ,
264- dropdown = id_val [ "selector" ] in [ "colormap" ] ,
341+ color_tables = color_tables ,
265342 )
266343 for id_val in color_wrapper_ids
267344 ],
@@ -305,7 +382,7 @@ def _update_color_store(
305382 # 5th callback
306383 @callback (
307384 Output ({"id" : get_uuid (LayoutElements .DECKGLMAP ), "tab" : MATCH }, "layers" ),
308- # Output({"id": get_uuid(LayoutElements.DECKGLMAP), "tab": MATCH}, "bounds"),
385+ Output ({"id" : get_uuid (LayoutElements .DECKGLMAP ), "tab" : MATCH }, "bounds" ),
309386 Output ({"id" : get_uuid (LayoutElements .DECKGLMAP ), "tab" : MATCH }, "views" ),
310387 Output ({"id" : get_uuid (LayoutElements .DECKGLMAP ), "tab" : MATCH }, "children" ),
311388 Input (
@@ -316,6 +393,7 @@ def _update_color_store(
316393 Input (get_uuid (LayoutElements .OPTIONS ), "value" ),
317394 State (get_uuid ("tabs" ), "value" ),
318395 State ({"id" : get_uuid (LayoutElements .MULTI ), "tab" : MATCH }, "value" ),
396+ State ({"id" : get_uuid (LayoutElements .DECKGLMAP ), "tab" : MATCH }, "bounds" ),
319397 )
320398 def _update_map (
321399 surface_elements : List [dict ],
@@ -324,6 +402,7 @@ def _update_map(
324402 options : List [str ],
325403 tab_name : str ,
326404 multi : str ,
405+ current_bounds : Optional [List ],
327406 ) -> tuple :
328407 """Updates the map component with the stored, validated selections"""
329408
@@ -336,6 +415,7 @@ def _update_map(
336415 view_columns = 3 if view_columns is None else view_columns
337416
338417 layers = update_map_layers (
418+ render_surfaces_as_images = isinstance (surface_server , SurfaceImageServer ),
339419 views = len (surface_elements ),
340420 include_well_layer = well_picks_provider is not None ,
341421 visible_well_layer = LayoutLabels .SHOW_WELLS in options ,
@@ -345,42 +425,61 @@ def _update_map(
345425
346426 for idx , data in enumerate (surface_elements ):
347427 diff_surf = data .get ("surf_type" ) == "diff"
348- surf_meta , mesh_url = (
428+ surf_meta , surface_url = (
349429 get_surface_metadata_and_image (data )
350430 if not diff_surf
351431 else get_surface_metadata_and_image_for_diff_surface (surface_elements )
352432 )
433+ viewport_bounds = [
434+ surf_meta .x_min ,
435+ surf_meta .y_min ,
436+ surf_meta .x_max ,
437+ surf_meta .y_max ,
438+ ]
353439 if (
354440 data ["color_range" ][0 ] != surf_meta .val_min
355441 or data ["color_range" ][1 ] != surf_meta .val_max
356442 ):
357443 color_range = data ["color_range" ]
358444 else :
359445 color_range = None
360- layer_data = {
361- "meshUrl" : mesh_url ,
362- "frame" : {
363- "origin" : [surf_meta .x_ori , surf_meta .y_ori ],
364- "count" : [surf_meta .x_count , surf_meta .y_count ],
365- "increment" : [surf_meta .x_inc , surf_meta .y_inc ],
366- "rotDeg" : surf_meta .rot_deg ,
367- },
368- "colorMapName" : data ["colormap" ],
369- "colorMapRange" : color_range ,
370- }
371- layer_idx = None
372- for layer in layers :
373- if layer ["id" ] == f"{ LayoutElements .MAP3D_LAYER } -{ idx } " :
374- layer_idx = layers .index (layer )
375- break
376- if layer_idx is not None :
377- layers [layer_idx ].update (layer_data )
446+ if isinstance (surface_server , SurfaceArrayServer ):
447+ layer_data = {
448+ "meshUrl" : surface_url ,
449+ "frame" : {
450+ "origin" : [surf_meta .x_ori , surf_meta .y_ori ],
451+ "count" : [surf_meta .x_count , surf_meta .y_count ],
452+ "increment" : [surf_meta .x_inc , surf_meta .y_inc ],
453+ "rotDeg" : surf_meta .rot_deg ,
454+ },
455+ "colorMapName" : data ["colormap" ],
456+ "colorMapRange" : color_range ,
457+ }
458+ layer_idx = None
459+ for layer in layers :
460+ if layer ["id" ] == f"{ LayoutElements .MAP3D_LAYER } -{ idx } " :
461+ layer_idx = layers .index (layer )
462+ break
463+ if layer_idx is not None :
464+ layers [layer_idx ].update (layer_data )
465+ else :
466+ layer_data ["id" ] = f"{ LayoutElements .MAP3D_LAYER } -{ idx } "
467+ layer_data ["@@type" ] = LayerTypes .MAP3D
468+ layer_data ["material" ] = False
469+ layers .insert (0 , layer_data )
378470 else :
379- layer_data ["id" ] = f"{ LayoutElements .MAP3D_LAYER } -{ idx } "
380- layer_data ["@@type" ] = LayerTypes .MAP3D
381- layer_data ["material" ] = False
382- layers .insert (0 , layer_data )
383-
471+ layer_data = {
472+ "image" : surface_url ,
473+ "bounds" : surf_meta .deckgl_bounds ,
474+ "rotDeg" : surf_meta .deckgl_rot_deg ,
475+ "valueRange" : [surf_meta .val_min , surf_meta .val_max ],
476+ "colorMapName" : data ["colormap" ],
477+ "colorMapRange" : color_range ,
478+ }
479+ layer_model .update_layer_by_id (
480+ layer_id = f"{ LayoutElements .COLORMAP_LAYER } -{ idx } " ,
481+ layer_data = layer_data ,
482+ )
384483 if (
385484 LayoutLabels .SHOW_FAULTPOLYGONS in options
386485 and fault_polygon_attribute is not None
@@ -434,6 +533,7 @@ def _update_map(
434533 openColorSelector = False ,
435534 legendScaleSize = 0.1 ,
436535 legendFontSize = 30 ,
536+ colorTables = color_tables ,
437537 ),
438538 wsc .ViewFooter (
439539 children = make_viewport_label (
@@ -449,7 +549,9 @@ def _update_map(
449549 "show3D" : False ,
450550 "isSync" : True ,
451551 "layerIds" : [
452- f"{ LayoutElements .MAP3D_LAYER } -{ idx } " ,
552+ f"{ LayoutElements .MAP3D_LAYER } -{ idx } "
553+ if isinstance (surface_server , SurfaceArrayServer )
554+ else f"{ LayoutElements .COLORMAP_LAYER } -{ idx } " ,
453555 f"{ LayoutElements .FAULTPOLYGONS_LAYER } -{ idx } " ,
454556 f"{ LayoutElements .WELLS_LAYER } -{ idx } " ,
455557 ],
@@ -463,6 +565,7 @@ def _update_map(
463565 }
464566 return (
465567 layer_model .layers ,
568+ viewport_bounds if not current_bounds else no_update ,
466569 views ,
467570 view_annotations ,
468571 )
0 commit comments