1# https://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from __future__ import absolute_import, print_function, division
8from pyrocko.plot import automap
9from pyrocko.dataset.topo import tile
10from pyrocko.guts import String
11from pyrocko.dataset import topo
12from pyrocko.gui.qt_compat import qw, qc
14from pyrocko.gui.vtk_util import cpt_to_vtk_lookuptable
16from .base import Element
17from .topo import TopoMeshPipe, TopoCPTChoice, TopoState
19from .. import common
21guts_prefix = 'sparrow'
24class CustomTopoState(TopoState):
25 path = String.T(optional=True)
27 def create(self):
28 element = CustomTopoElement()
29 return element
32class CustomTopoElement(Element):
34 def __init__(self):
35 Element.__init__(self)
36 self._parent = None
37 self._controls = None
38 self._visible = False
39 self._mesh = None
40 self._lookuptables = {}
41 self._path_loaded = None
43 def get_name(self):
44 return 'Custom Topography'
46 def bind_state(self, state):
47 Element.bind_state(self, state)
48 self.register_state_listener3(self.update, state, 'visible')
49 self.register_state_listener3(self.update, state, 'exaggeration')
50 self.register_state_listener3(self.update, state, 'opacity')
51 self.register_state_listener3(self.update, state, 'smooth')
52 self.register_state_listener3(self.update, state, 'cpt')
53 self.register_state_listener3(self.update, state, 'path')
55 def set_parent(self, parent):
56 self._parent = parent
58 self._parent.add_panel(
59 self.get_name(),
60 self._get_controls(),
61 visible=True,
62 title_controls=[
63 self.get_title_control_remove(),
64 self.get_title_control_visible()])
66 self.update()
68 def unset_parent(self):
69 self.unbind_state()
70 if self._parent:
71 if self._mesh is not None:
72 self._parent.remove_actor(self._mesh.actor)
74 self._mesh = None
76 if self._controls:
77 self._parent.remove_panel(self._controls)
78 self._controls = None
80 self._parent.update_view()
81 self._parent = None
83 def update_cpt(self, cpt_name):
84 if cpt_name not in self._lookuptables:
85 if cpt_name == 'light':
86 topo_cpt_wet = 'light_sea'
87 topo_cpt_dry = 'light_land'
89 elif cpt_name == 'uniform':
90 topo_cpt_wet = 'light_sea_uniform'
91 topo_cpt_dry = 'light_land_uniform'
93 cpt_wet = automap.read_cpt(topo.cpt(topo_cpt_wet))
94 cpt_dry = automap.read_cpt(topo.cpt(topo_cpt_dry))
95 cpt_combi = automap.cpt_merge_wet_dry(cpt_wet, cpt_dry)
97 lut_combi = cpt_to_vtk_lookuptable(cpt_combi)
98 lut_combi.SetNanColor(0.0, 0.0, 0.0, 0.0)
100 self._lookuptables[cpt_name] = lut_combi
102 def update(self, *args):
103 visible = self._state.visible
105 self.update_cpt(self._state.cpt)
107 if visible:
108 if self._path_loaded is None and self._state.path is not None or \
109 self._state.path != self._path_loaded:
111 if self._mesh:
112 self._parent.remove_actor(self._mesh.actor)
113 self._mesh = None
115 t = tile.Tile.from_grd(self._state.path)
116 self._path_loaded = self._state.path
117 self._mesh = TopoMeshPipe(
118 t,
119 mask_ocean=False,
120 smooth=self._state.smooth,
121 lut=self._lookuptables[self._state.cpt])
123 self._parent.add_actor(self._mesh.actor)
125 if not visible and self._mesh:
126 self._parent.remove_actor(self._mesh.actor)
128 if self._mesh:
129 if visible:
130 self._parent.add_actor(self._mesh.actor)
132 self._mesh.set_exaggeration(self._state.exaggeration)
133 self._mesh.set_opacity(self._state.opacity)
134 self._mesh.set_smooth(self._state.smooth)
135 self._mesh.set_lookuptable(
136 self._lookuptables[self._state.cpt])
138 self._parent.update_view()
140 def open_file_dialog(self):
141 caption = 'Select a file to open'
143 fn, _ = qw.QFileDialog.getOpenFileName(
144 self._parent, caption, options=common.qfiledialog_options)
146 if fn:
147 self._state.path = str(fn)
149 def _get_controls(self):
150 state = self._state
151 if not self._controls:
152 from ..state import state_bind_slider, state_bind_checkbox, \
153 state_bind_combobox
155 frame = qw.QFrame()
156 layout = qw.QGridLayout()
157 frame.setLayout(layout)
159 lab = qw.QLabel('Load from:')
160 pb_file = qw.QPushButton('File')
162 layout.addWidget(lab, 0, 0)
163 layout.addWidget(pb_file, 0, 1)
165 pb_file.clicked.connect(self.open_file_dialog)
167 # exaggeration
169 layout.addWidget(qw.QLabel('Exaggeration'), 1, 0)
171 slider = qw.QSlider(qc.Qt.Horizontal)
172 slider.setSizePolicy(
173 qw.QSizePolicy(
174 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
175 slider.setMinimum(0)
176 slider.setMaximum(2000)
177 layout.addWidget(slider, 1, 1)
179 state_bind_slider(self, state, 'exaggeration', slider, factor=0.01)
181 # opacity
183 layout.addWidget(qw.QLabel('Opacity'), 2, 0)
185 slider = qw.QSlider(qc.Qt.Horizontal)
186 slider.setSizePolicy(
187 qw.QSizePolicy(
188 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
189 slider.setMinimum(0)
190 slider.setMaximum(1000)
191 layout.addWidget(slider, 2, 1)
193 state_bind_slider(self, state, 'opacity', slider, factor=0.001)
195 cb = qw.QCheckBox('Smooth')
196 layout.addWidget(cb, 3, 1)
197 state_bind_checkbox(self, state, 'smooth', cb)
199 cb = common.string_choices_to_combobox(TopoCPTChoice)
200 layout.addWidget(qw.QLabel('CPT'), 4, 0)
201 layout.addWidget(cb, 4, 1)
202 state_bind_combobox(self, state, 'cpt', cb)
204 layout.addWidget(qw.QFrame(), 6, 0, 1, 2)
206 self._controls = frame
208 return self._controls
211__all__ = [
212 'CustomTopoElement',
213 'CustomTopoState',
214]