1# https://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6import numpy as num 

7 

8from pyrocko import table, geometry, cake 

9from pyrocko.guts import Bool, Float 

10from pyrocko.gui.qt_compat import qw, qc 

11 

12from pyrocko.dataset.tectonics import PeterBird2003 

13from pyrocko.gui import vtk_util 

14import vtk 

15from matplotlib.pyplot import cm 

16 

17from .base import Element, ElementState 

18 

19guts_prefix = 'sparrow' 

20 

21km = 1e3 

22COLOR_PLATES = (0.1, 0.0, .0) 

23 

24 

25def plates_to_points(plates): 

26 num_all_nodes = 0 

27 for plate in plates: 

28 num_all_nodes = num_all_nodes + len(plate.points) 

29 coords = num.zeros((num_all_nodes, 3)) 

30 x = [] 

31 y = [] 

32 

33 for plate in plates: 

34 num_nodes = len(plate.points) 

35 for i in range(0, num_nodes): 

36 x.append(plate.points[i][0]) 

37 y.append(plate.points[i][1]) 

38 for i in range(0, num_all_nodes): 

39 coords[i, :] = x[i], y[i], -10*km 

40 station_table = table.Table() 

41 

42 station_table.add_col(('coords', '', ('lat', 'lon', 'depth')), coords) 

43 

44 return geometry.latlondepth2xyz( 

45 station_table.get_col('coords'), 

46 planetradius=cake.earthradius) 

47 

48 

49def plates_to_color(plates): 

50 colors = [] 

51 colors_iter_map = iter(cm.terrain(num.linspace(0, 1, len(plates)))) 

52 for plate in plates: 

53 color = next(colors_iter_map) 

54 colors.append(color) 

55 return num.array(colors) 

56 

57 

58class PlatesBoundsState(ElementState): 

59 visible = Bool.T(default=True) 

60 opacity = Float.T(default=1.0) 

61 color_by_slip_type = Bool.T(default=False) 

62 lines = Bool.T(default=True) 

63 

64 def create(self): 

65 element = PlatesBoundsElement() 

66 return element 

67 

68 

69class PlatelinesPipe(object): 

70 def __init__(self, plates=None): 

71 

72 self.mapper = vtk.vtkDataSetMapper() 

73 self._polyline_grid = {} 

74 self._opacity = 1.0 

75 self.plates = plates 

76 

77 actor = vtk.vtkActor() 

78 actor.SetMapper(self.mapper) 

79 

80 prop = actor.GetProperty() 

81 prop.SetDiffuseColor(1, 1, 1) 

82 

83 self.prop = prop 

84 self.actor = actor 

85 

86 def plate_to_lines(self, plate): 

87 lines = [] 

88 poly = [] 

89 num_nodes = len(plate.points) 

90 for i in range(0, num_nodes): 

91 poly.append((plate.points[i][0], plate.points[i][1])) 

92 lines.append(num.asarray(poly)) 

93 

94 self._polyline_grid[0] = vtk_util.make_multi_polyline( 

95 lines_latlon=lines, depth=-100.) 

96 vtk_util.vtk_set_input(self.mapper, self._polyline_grid[0]) 

97 

98 def set_opacity(self, opacity): 

99 opacity = float(opacity) 

100 if self._opacity != opacity: 

101 self.prop.SetOpacity(opacity) 

102 self._opacity = opacity 

103 

104 

105class PlatesBoundsElement(Element): 

106 

107 def __init__(self): 

108 Element.__init__(self) 

109 self._parent = None 

110 self._state = None 

111 self._pipe = None 

112 self._controls = None 

113 self._plates = None 

114 self._listeners = [] 

115 self._plate_line = None 

116 self._plate_lines = [] 

117 

118 def bind_state(self, state): 

119 Element.bind_state(self, state) 

120 for var in ['visible', 'opacity']: 

121 self.register_state_listener3(self.update, state, var) 

122 

123 def unbind_state(self): 

124 self._listerners = [] 

125 

126 def get_name(self): 

127 return 'Plate bounds' 

128 

129 def set_parent(self, parent): 

130 self._parent = parent 

131 if not self._plates: 

132 PB = PeterBird2003() 

133 self._plates = PB.get_plates() 

134 

135 self._parent.add_panel( 

136 self.get_name(), 

137 self._get_controls(), 

138 visible=True, 

139 title_controls=[ 

140 self.get_title_control_remove(), 

141 self.get_title_control_visible()]) 

142 

143 self.update() 

144 

145 def unset_parent(self): 

146 self.unbind_state() 

147 if self._plate_lines: 

148 for i, plate in enumerate(self._plate_lines): 

149 self._parent.remove_actor(plate.actor) 

150 

151 self._pipe = None 

152 

153 if self._controls: 

154 self._parent.remove_panel(self._controls) 

155 self._controls = None 

156 

157 self._parent.update_view() 

158 self._parent = None 

159 

160 def update(self, *args): 

161 

162 state = self._state 

163 if state.visible: 

164 colors = plates_to_color(self._plates) 

165 for i, plate in enumerate(self._plates): 

166 self._plate_line = PlatelinesPipe(plates=plate) 

167 self._plate_line.plate_to_lines(plate) 

168 self._parent.add_actor(self._plate_line.actor) 

169 prop = self._plate_line.actor.GetProperty() 

170 prop.SetDiffuseColor(colors[i][0:3]) 

171 self._plate_line.set_opacity(state.opacity) 

172 self._plate_lines.append(self._plate_line) 

173 if not state.visible and self._plate_lines: 

174 for i, plate in enumerate(self._plate_lines): 

175 self._parent.remove_actor(plate.actor) 

176 

177 self._parent.update_view() 

178 

179 def _get_controls(self): 

180 if self._controls is None: 

181 from ..state import state_bind_slider 

182 

183 frame = qw.QFrame() 

184 layout = qw.QGridLayout() 

185 layout.setAlignment(qc.Qt.AlignTop) 

186 frame.setLayout(layout) 

187 

188 layout.addWidget(qw.QLabel('Opacity'), 0, 0) 

189 

190 slider = qw.QSlider(qc.Qt.Horizontal) 

191 slider.setSizePolicy( 

192 qw.QSizePolicy( 

193 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed)) 

194 slider.setMinimum(0) 

195 slider.setMaximum(10) 

196 slider.setSingleStep(1) 

197 slider.setPageStep(1) 

198 layout.addWidget(slider, 0, 1) 

199 state_bind_slider(self, self._state, 'opacity', slider) 

200 

201 layout.addWidget(qw.QFrame(), 1, 0, 1, 2) 

202 

203 self._controls = frame 

204 

205 return self._controls 

206 

207 

208__all__ = [ 

209 'PlatesBoundsElement', 

210 'PlatesBoundsState' 

211]