1# https://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5 

6from __future__ import absolute_import, print_function, division 

7 

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 

13 

14from pyrocko.gui.vtk_util import cpt_to_vtk_lookuptable 

15 

16from .base import Element 

17from .topo import TopoMeshPipe, TopoCPTChoice, TopoState 

18 

19from .. import common 

20 

21guts_prefix = 'sparrow' 

22 

23 

24class CustomTopoState(TopoState): 

25 path = String.T(optional=True) 

26 

27 def create(self): 

28 element = CustomTopoElement() 

29 return element 

30 

31 

32class CustomTopoElement(Element): 

33 

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 

42 

43 def get_name(self): 

44 return 'Custom Topography' 

45 

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') 

54 

55 def set_parent(self, parent): 

56 self._parent = parent 

57 

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()]) 

65 

66 self.update() 

67 

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) 

73 

74 self._mesh = None 

75 

76 if self._controls: 

77 self._parent.remove_panel(self._controls) 

78 self._controls = None 

79 

80 self._parent.update_view() 

81 self._parent = None 

82 

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' 

88 

89 elif cpt_name == 'uniform': 

90 topo_cpt_wet = 'light_sea_uniform' 

91 topo_cpt_dry = 'light_land_uniform' 

92 

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) 

96 

97 lut_combi = cpt_to_vtk_lookuptable(cpt_combi) 

98 lut_combi.SetNanColor(0.0, 0.0, 0.0, 0.0) 

99 

100 self._lookuptables[cpt_name] = lut_combi 

101 

102 def update(self, *args): 

103 visible = self._state.visible 

104 

105 self.update_cpt(self._state.cpt) 

106 

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: 

110 

111 if self._mesh: 

112 self._parent.remove_actor(self._mesh.actor) 

113 self._mesh = None 

114 

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]) 

122 

123 self._parent.add_actor(self._mesh.actor) 

124 

125 if not visible and self._mesh: 

126 self._parent.remove_actor(self._mesh.actor) 

127 

128 if self._mesh: 

129 if visible: 

130 self._parent.add_actor(self._mesh.actor) 

131 

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]) 

137 

138 self._parent.update_view() 

139 

140 def open_file_dialog(self): 

141 caption = 'Select a file to open' 

142 

143 fn, _ = qw.QFileDialog.getOpenFileName( 

144 self._parent, caption, options=common.qfiledialog_options) 

145 

146 if fn: 

147 self._state.path = str(fn) 

148 

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 

154 

155 frame = qw.QFrame() 

156 layout = qw.QGridLayout() 

157 frame.setLayout(layout) 

158 

159 lab = qw.QLabel('Load from:') 

160 pb_file = qw.QPushButton('File') 

161 

162 layout.addWidget(lab, 0, 0) 

163 layout.addWidget(pb_file, 0, 1) 

164 

165 pb_file.clicked.connect(self.open_file_dialog) 

166 

167 # exaggeration 

168 

169 layout.addWidget(qw.QLabel('Exaggeration'), 1, 0) 

170 

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) 

178 

179 state_bind_slider(self, state, 'exaggeration', slider, factor=0.01) 

180 

181 # opacity 

182 

183 layout.addWidget(qw.QLabel('Opacity'), 2, 0) 

184 

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) 

192 

193 state_bind_slider(self, state, 'opacity', slider, factor=0.001) 

194 

195 cb = qw.QCheckBox('Smooth') 

196 layout.addWidget(cb, 3, 1) 

197 state_bind_checkbox(self, state, 'smooth', cb) 

198 

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) 

203 

204 layout.addWidget(qw.QFrame(), 6, 0, 1, 2) 

205 

206 self._controls = frame 

207 

208 return self._controls 

209 

210 

211__all__ = [ 

212 'CustomTopoElement', 

213 'CustomTopoState', 

214]